/// <summary>
        /// This should be called at the end of any method that alters the
        /// storage in any way.  This method will make sure the peer dp is
        /// set correctly and notify Animatables if something changes.
        /// </summary>
        internal void WritePostscript()
        {
            DependencyObject d = (DependencyObject)_dependencyObject.Target;

            if (d == null)
            {
                return;
            }

            FrugalMap animatedPropertyMap = AnimatedPropertyMapField.GetValue(d);

            if (animatedPropertyMap.Count == 0 ||
                animatedPropertyMap[_dependencyProperty.GlobalIndex] == DependencyProperty.UnsetValue)
            {
                if (!IsEmpty)
                {
                    // This is kind of tricky:
                    //
                    // Because FrugalMap is a struct instead of a class, we must
                    // be sure to add this AnimationStorage to the map before
                    // setting the FrugalMap into the UncommonField storage. If
                    // we don't and the FrugalMap is empty then an empty FrugalMap
                    // will be set into the UncommonField storage. If we were to
                    // then add our AnimationStorage to the local FrugalMap, it
                    // would only allocate its own internal storage at that point
                    // which would not apply to the FrugalMap we set into the
                    // UncommonField storage. Once a FrugalMap has allocated its
                    // internal storage, though, that storage is copied with the
                    // FrugalMap. This is what will happen when we add our
                    // AnimationStorage to the FrugalMap first as we do below:

                    animatedPropertyMap[_dependencyProperty.GlobalIndex] = this;

                    // Since FrugalMap is a struct and adding a new value to it
                    // may re-allocate the storage, we need to set this value
                    // each time we make a change to the map.

                    AnimatedPropertyMapField.SetValue(d, animatedPropertyMap);

                    if (animatedPropertyMap.Count == 1)
                    {
                        d.IAnimatable_HasAnimatedProperties = true;
                    }

                    // If this the target is an Animatable we'll need to
                    // invalidate it so that the animation resource for this
                    // newly animated property will be passed across to the UCE.
                    Animatable a = d as Animatable;

                    if (a != null)
                    {
                        a.RegisterForAsyncUpdateResource();
                    }

                    // If this AnimationStorage is a resource, add it to the
                    // channel now.
                    DUCE.IResource animationResource = this as DUCE.IResource;

                    if (animationResource != null)
                    {
                        DUCE.IResource targetResource = d as DUCE.IResource;

                        if (targetResource != null)
                        {
                            using (CompositionEngineLock.Acquire())
                            {
                                int channelCount = targetResource.GetChannelCount();

                                for (int i = 0; i < channelCount; i++)
                                {
                                    DUCE.Channel channel = targetResource.GetChannel(i);
                                    if (!targetResource.GetHandle(channel).IsNull)
                                    {
                                        animationResource.AddRefOnChannel(channel);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                Debug.Assert(animatedPropertyMap.Count > 0);
                Debug.Assert(animatedPropertyMap[_dependencyProperty.GlobalIndex] != DependencyProperty.UnsetValue);

                if (IsEmpty)
                {
                    // If this AnimationStorage is a resource, release it from
                    // the channel now.
                    DUCE.IResource animationResource = this as DUCE.IResource;

                    if (animationResource != null)
                    {
                        DUCE.IResource targetResource = d as DUCE.IResource;

                        if (targetResource != null)
                        {
                            using (CompositionEngineLock.Acquire())
                            {
                                int channelCount = targetResource.GetChannelCount();

                                for (int i = 0; i < channelCount; i++)
                                {
                                    DUCE.Channel channel = targetResource.GetChannel(i);
                                    if (!targetResource.GetHandle(channel).IsNull)
                                    {
                                        animationResource.ReleaseOnChannel(channel);
                                    }
                                }
                            }
                        }
                    }

                    // If this the target is an Animatable we'll need to
                    // invalidate it so that the animation resource for this
                    // no longer animated property will no longer be passed
                    // across to the UCE.
                    Animatable a = d as Animatable;

                    if (a != null)
                    {
                        a.RegisterForAsyncUpdateResource();
                    }

                    animatedPropertyMap[_dependencyProperty.GlobalIndex] = DependencyProperty.UnsetValue;

                    if (animatedPropertyMap.Count == 0)
                    {
                        AnimatedPropertyMapField.ClearValue(d);

                        d.IAnimatable_HasAnimatedProperties = false;
                    }
                    else
                    {
                        AnimatedPropertyMapField.SetValue(d, animatedPropertyMap);
                    }

                    // We've removed animation storage for this DP, so if we were storing the local
                    // base value here then it has to go back to its non-animated storage spot.
                    if (_baseValue != DependencyProperty.UnsetValue)
                    {
                        d.SetValue(_dependencyProperty, _baseValue);
                    }
                }
            }

            // recompute animated value
            d.InvalidateProperty(_dependencyProperty);
        }