/// <summary>
        /// Gets the InterfaceDuckProxyType object for a given cast.
        /// </summary>
        /// <param name="interfaceType">Type to cast to.</param>
        /// <param name="duckType">Static type being casted.</param>
        /// <returns>The duck proxy type to use to cast or prepare for casting.</returns>
        private InterfaceDuckProxyType GetProxyType(Type interfaceType, Type duckType)
        {
            InterfaceDuckProxyType proxyType = null;

            FromTypeTree<InterfaceDuckProxyType> fromTypeTree = null;

            if (s_ProxyTypeTree.ContainsKey(interfaceType))
            {
                fromTypeTree = s_ProxyTypeTree[interfaceType];

                if (fromTypeTree.ContainsKey(duckType))
                {
                    proxyType = fromTypeTree[duckType];
                }
            }

            if (proxyType == null)
            {
                proxyType = new InterfaceDuckProxyType(interfaceType, duckType, true);
                
                if (fromTypeTree == null)
                {
                    fromTypeTree = new FromTypeTree<InterfaceDuckProxyType>();
                    s_ProxyTypeTree.Add(interfaceType, fromTypeTree);
                }

                fromTypeTree.Add(proxyType.DuckType, proxyType);
            }

            return proxyType;
        }
        /// <summary>
        /// Gets the InterfaceDuckProxyType object for a given cast.
        /// </summary>
        /// <remarks>
        /// First, the most general type in the inheritance chain of the given type that implements all the 
        /// members of TInterface is selected.  Then if a proxy type has already been generated, it returns 
        /// it.  Finally, if not, it creates a new object and adds it to the dictionary.
        /// </remarks>
        /// <param name="interfaceType">Type to cast to.</param>
        /// <param name="duckType">Type of object being casted.</param>
        /// <returns>The duck proxy type to use to cast or prepare for casting.</returns>
        private InterfaceDuckProxyType GetProxyType(Type interfaceType, Type duckType)
        {
            InterfaceDuckProxyType proxyType = null;

            FromTypeTree<InterfaceDuckProxyType> fromTypeTree = null;

            // Examine the duck type's inheritance chain.
            List<Type> inheritanceChain = new List<Type>();
            Type baseType = duckType;
            do
            {
                inheritanceChain.Add(baseType);
                baseType = baseType.BaseType;
            }
            while (baseType != null);

            // Include interfaces in the inheritance chain.  We don't know which order, but it will still help.
            /*Type[] interfaces = duckType.GetInterfaces();
            foreach (Type _interface in interfaces)
            {
                inheritanceChain.Add(_interface);
            }*/

            if (s_ProxyTypeTree.ContainsKey(interfaceType))
            {
                fromTypeTree = s_ProxyTypeTree[interfaceType];

                // Iterate the inheritance chain backwards (most general to most specialized) to find a proxy type
                // that has already been generated.
                for (int i = inheritanceChain.Count - 1; i >= 0; i--)
                {
                    Type type = inheritanceChain[i];

                    if (fromTypeTree.ContainsKey(type))
                    {
                        proxyType = fromTypeTree[type];
                        break;
                    }
                }
            }

            if (proxyType == null)
            {
                // Iterate the inheritance chain backwards (most general to most specialized) to find the most 
                // general type that can be casted to TInterface.
                for (int i = inheritanceChain.Count - 1; i >= 0; i--)
                {
                    Type type = inheritanceChain[i];

                    if (CanCast(interfaceType, type))
                    {
                        proxyType = new InterfaceDuckProxyType(interfaceType, type, false);
                        break;
                    }
                }

                if (proxyType == null)
                {
                    // If proxyType is null, then DuckTyping.CanCast<>() returned false for every type in the
                    // inheritance chain.  The following line will cause an exception to be thrown when 
                    // GenerateProxyType() is called.  The exception will indicate why the duck cannot be casted.
                    proxyType = new InterfaceDuckProxyType(interfaceType, duckType, false);
                }
                else
                {
                    // If we got to this point, the cast is valid and it is ok to add the proxy type to the tree.
                    if (fromTypeTree == null)
                    {
                        fromTypeTree = new FromTypeTree<InterfaceDuckProxyType>();
                        s_ProxyTypeTree.Add(interfaceType, fromTypeTree);
                    }

                    fromTypeTree.Add(proxyType.DuckType, proxyType);
                }
            }

            return proxyType;
        }