/// <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);
        }