//    Description:
        //        Write out the anim curve from the clipboard item into the
        //        stream. The actual anim curve data is written out.
        //
        //        This method returns true if the write was successful.
        //
        protected void writeAnimCurve(ref StreamWriter clip, 
            MObject animCurveObj,
            MFnAnimCurve.AnimCurveType type,
            bool verboseUnits = false)
        {
            if (clip == null)
            {
                throw new ArgumentNullException( "clip" );
            }

            if (null == animCurveObj || animCurveObj.isNull)
            {
                throw new ArgumentNullException( "animCurveObj" );
            }

            MFnAnimCurve animCurve = new MFnAnimCurve(animCurveObj);

            clip.Write(kAnimData + kSpaceChar + kBraceLeftChar + Environment.NewLine);

            clip.Write(kTwoSpace + kInputString + kSpaceChar +
                    boolInputTypeAsWord(animCurve.isUnitlessInput) +
                    kSemiColonChar + Environment.NewLine);

            clip.Write( kTwoSpace + kOutputString + kSpaceChar +
                    outputTypeAsWord(type) + kSemiColonChar + Environment.NewLine);

            clip.Write(kTwoSpace + kWeightedString + kSpaceChar +
                    Convert.ToString(animCurve.isWeighted ? 1 : 0) + kSemiColonChar +Environment.NewLine);

            //	These units default to the units in the header of the file.
            //
            if (verboseUnits)
            {
                clip.Write(kTwoSpace + kInputUnitString + kSpaceChar);
                if (animCurve.isTimeInput)
                {
                    string unitName = "";
                    animUnitNames.setToShortName(timeUnit, ref unitName);
                    clip.Write(unitName);
                }
                else
                {
                    //	The anim curve has unitless input.
                    //
                    clip.Write(animUnitNames.kUnitlessString);
                }

                clip.Write(kSemiColonChar + Environment.NewLine);

                clip.Write(kTwoSpace + kOutputUnitString + kSpaceChar);
            }

            double conversion = 1.0;
            switch (type)
            {
                case MFnAnimCurve.AnimCurveType.kAnimCurveTA:
                case MFnAnimCurve.AnimCurveType.kAnimCurveUA:
                    {
                        string unitName = "";
                        animUnitNames.setToShortName(angularUnit, ref unitName);
                        if (verboseUnits) clip.Write(unitName);
                        {
                            MAngle angle = new MAngle(1.0);
                            conversion = angle.asUnits(angularUnit);
                        }
                        break;
                    }
                case MFnAnimCurve.AnimCurveType.kAnimCurveTL:
                case MFnAnimCurve.AnimCurveType.kAnimCurveUL:
                    {
                        string unitName = "";
                        animUnitNames.setToShortName(linearUnit, ref unitName);
                        if (verboseUnits) clip.Write(unitName);
                        {
                            MDistance distance = new MDistance(1.0);
                            conversion = distance.asUnits(linearUnit);
                        }
                        break;
                    }
                case MFnAnimCurve.AnimCurveType.kAnimCurveTT:
                case MFnAnimCurve.AnimCurveType.kAnimCurveUT:
                    {
                        string unitName = "";
                        animUnitNames.setToShortName(timeUnit, ref unitName);
                        if (verboseUnits) clip.Write(unitName);
                        break;
                    }
                default:
                    if (verboseUnits) clip.Write(animUnitNames.kUnitlessString);
                    break;
            }

            if (verboseUnits) clip.Write(kSemiColonChar +Environment.NewLine);

            if (verboseUnits)
            {
                string angleUnitName = "";
                animUnitNames.setToShortName(angularUnit, ref angleUnitName);
                clip.Write(kTwoSpace + kTanAngleUnitString +
                        kSpaceChar + angleUnitName + kSemiColonChar + Environment.NewLine);
            }

            clip.Write(kTwoSpace + kPreInfinityString + kSpaceChar +
                    infinityTypeAsWord(animCurve.preInfinityType) +
                    kSemiColonChar + Environment.NewLine);

            clip.Write(kTwoSpace + kPostInfinityString + kSpaceChar +
                    infinityTypeAsWord(animCurve.postInfinityType) +
                    kSemiColonChar + Environment.NewLine);

            clip.Write(kTwoSpace + kKeysString + kSpaceChar + kBraceLeftChar + Environment.NewLine);

            // And then write out each keyframe
            //
            uint numKeys = animCurve.numKeyframes;
            for (uint i = 0; i < numKeys; i++)
            {
                clip.Write(kTwoSpace + kTwoSpace);
                if (animCurve.isUnitlessInput)
                {
                    clip.Write(animCurve.unitlessInput(i));
                }
                else
                {
                    clip.Write(animCurve.time(i).value);
                }

                // clamp tiny values so that it isn't so small it can't be read in
                //
                double animValue = (conversion*animCurve.value(i));
                if (isEquivalent(animValue,0.0))
                    animValue = 0.0;
                clip.Write(kSpaceChar + Convert.ToString(animValue));

                clip.Write(kSpaceChar + tangentTypeAsWord(animCurve.inTangentType(i)) );
                clip.Write(kSpaceChar + tangentTypeAsWord(animCurve.outTangentType(i)) );

                clip.Write( kSpaceChar + Convert.ToString(animCurve.tangentsLocked(i) ? 1 : 0));
                clip.Write(kSpaceChar + Convert.ToString(animCurve.weightsLocked(i) ? 1 : 0));
                clip.Write(kSpaceChar + Convert.ToString(animCurve.isBreakdown(i) ? 1 : 0));

                if (animCurve.inTangentType(i) == MFnAnimCurve.TangentType.kTangentFixed)
                {
                    MAngle angle = new MAngle();
                    double weight = 0.0;
                    animCurve.getTangent(i, angle, ref weight, true);

                    clip.Write(kSpaceChar + Convert.ToString(angle.asUnits(angularUnit)));
                    clip.Write(kSpaceChar + Convert.ToString(weight));
                }
                if (animCurve.outTangentType(i) == MFnAnimCurve.TangentType.kTangentFixed)
                {
                    MAngle angle = new MAngle();
                    double weight = 0.0;
                    animCurve.getTangent(i, angle, ref weight, false);

                    clip.Write(kSpaceChar +  Convert.ToString(angle.asUnits(angularUnit)));
                    clip.Write(kSpaceChar + Convert.ToString(weight));
                }

                clip.Write(kSemiColonChar + Environment.NewLine);
            }
            clip.Write(kTwoSpace + kBraceRightChar + Environment.NewLine);

            clip.Write(kBraceRightChar + Environment.NewLine);
        }