/// <summary> Creates a new TypeCollision using this types generic list w/ the specified
        /// non-generic type as the TypeCollision's ReflectedType.</summary>
        internal TypeCollision CloneWithNewBase(Type newBase)
        {
            Debug.Assert(!newBase.ContainsGenericParameters);

            TypeCollision res = new TypeCollision(newBase);
            res.types.AddRange(types);

            if (type.ContainsGenericParameters) {
                // if we have a collision between two non-generic
                // types new newer type simply wins.
                res.types.Add((ReflectedType)Ops.GetDynamicTypeFromType(type));
            }
            return res;
        }
        internal DynamicType SaveType(Type type)
        {
            string name = GetCoreTypeName(type);
            object existingType;

            // if there's no collisions we just save the type
            if (!__dict__.TryGetValue(SymbolTable.StringToId(name), out existingType)) {
                DynamicType ret;
                __dict__[SymbolTable.StringToId(name)] = ret = Ops.GetDynamicTypeFromType(type);
                return ret;
            }

            // two types w/ the same name.  Good examples are:
            //      System.Nullable and System.Nullable<T>
            //      System.IComparable vs System.IComparable<T>
            //    In this case we need to allow the user to disambiguate the two.
            //
            // Or we could have a recompile & reload cycle (or a really bad
            // collision).  In those cases the new type wins.

            TypeCollision tc = existingType as TypeCollision;
            if (tc != null) {
                // we've collided before...
                if (!type.ContainsGenericParameters) {
                    // we're replacing the existing non generic type
                    // or moving some random generic type from the "base"
                    // reflected type into the list of generics.
                    __dict__[SymbolTable.StringToId(name)] = tc = tc.CloneWithNewBase(type);
                } else {
                    // we're a generic type.  we just need to add
                    // ourselves to the list or replace an existing type
                    // of the same arity.
                    tc.UpdateType(type);
                }
            } else {
                // first time collision on this name, provide
                // the type collision to disambiguate.  The non-generic
                // is exposed by default, and the generic gets added
                // to the list to disambiguate.
                ReflectedType rt = existingType as ReflectedType;
                Debug.Assert(rt != null);

                if (rt.type.ContainsGenericParameters) {
                    // existing type has generics, append it.
                    tc = new TypeCollision(type);
                    __dict__[SymbolTable.StringToId(name)] = tc;
                    tc.UpdateType(rt.type);
                } else if (type.ContainsGenericParameters) {
                    // new type has generics, append it.
                    tc = new TypeCollision(rt.type);
                    __dict__[SymbolTable.StringToId(name)] = tc;
                    tc.UpdateType(type);
                } else {
                    // neither type has generics, replace the old
                    // non-generic type w/ the new non-generic type.
                    __dict__[SymbolTable.StringToId(name)] = Ops.GetDynamicTypeFromType(type);
                }
            }
            return tc;
        }