/// <summary>
        /// You register a transition with the manager here. This will start to run
        /// the transition as the manager's timer ticks.
        /// </summary>
        public void register(Transition transition)
        {
            lock (m_Lock)
            {
                // We check to see if the properties of this transition
                // are already being animated by any existing transitions...
                removeDuplicates(transition);

                // We add the transition to the collection we manage, and
                // observe it so that we know when it has completed...
                m_Transitions[transition] = true;
                transition.TransitionCompletedEvent += onTransitionCompleted;
            }
        }
        /// <summary>
        /// Finds any properties in the old-transition that are also in the new one,
        /// and removes them from the old one.
        /// </summary>
        private void removeDuplicates(Transition newTransition, Transition oldTransition)
        {
            // Note: This checking might be a bit more efficient if it did the checking
            //       with a set rather than looking through lists. That said, it is only done
            //       when transitions are added (which isn't very often) rather than on the
            //       timer, so I don't think this matters too much.

            // We get the list of properties for the old and new transitions...
            IList<Transition.TransitionedPropertyInfo> newProperties = newTransition.TransitionedProperties;
            IList<Transition.TransitionedPropertyInfo> oldProperties = oldTransition.TransitionedProperties;

            // We loop through the old properties backwards (as we may be removing
            // items from the list if we find a match)...
            for (int i = oldProperties.Count - 1; i >= 0; i--)
            {
                // We get one of the properties from the old transition...
                Transition.TransitionedPropertyInfo oldProperty = oldProperties[i];

                // Is this property part of the new transition?
                foreach (Transition.TransitionedPropertyInfo newProperty in newProperties)
                {
                    if (oldProperty.target == newProperty.target
                        &&
                        oldProperty.propertyInfo == newProperty.propertyInfo)
                    {
                        // The old transition contains the same property as the new one,
                        // so we remove it from the old transition...
                        oldTransition.removeProperty(oldProperty);
                    }
                }
            }
        }
        /// <summary>
        /// Called when a transition has completed. 
        /// </summary>
        private void onTransitionCompleted(object sender, Transition.Args e)
        {
            // We stop observing the transition...
            Transition transition = (Transition)sender;
            transition.TransitionCompletedEvent -= onTransitionCompleted;

            // We remove the transition from the collection we're managing...
            lock (m_Lock)
            {
                m_Transitions.Remove(transition);
            }
        }
 /// <summary>
 /// Checks if any existing transitions are acting on the same properties as the
 /// transition passed in. If so, we remove the duplicated properties from the 
 /// older transitions.
 /// </summary>
 private void removeDuplicates(Transition transition)
 {
     // We look through the set of transitions we're currently managing...
     foreach (KeyValuePair<Transition, bool> pair in m_Transitions)
     {
         removeDuplicates(transition, pair.Key);
     }
 }
 /// <summary>
 /// Creates and immediately runs a transition on the property passed in.
 /// </summary>
 public static void run(object target, string strPropertyName, object destinationValue, ITransitionType transitionMethod)
 {
     Transition t = new Transition(transitionMethod);
     t.add(target, strPropertyName, destinationValue);
     t.run();
 }