internal MetaTable GetTableNoLocks(Type rowType)
        {
            MetaTable table;

            if (!this.metaTables.TryGetValue(rowType, out table))
            {
                Type             root  = GetRoot(rowType) ?? rowType;
                TableAttribute[] attrs = (TableAttribute[])root.GetCustomAttributes(typeof(TableAttribute), true);

                if (attrs.Length == 0)
                {
                    this.metaTables.Add(rowType, null);
                }
                else
                {
                    if (!this.metaTables.TryGetValue(root, out table))
                    {
                        table = new AttributedMetaTable(this, attrs[0], root);

                        foreach (MetaType mt in table.RowType.InheritanceTypes)
                        {
                            this.metaTables.Add(mt.Type, table);
                        }
                    }

                    // catch case of derived type that is not part of inheritance

                    if (table.RowType.GetInheritanceType(rowType) == null)
                    {
                        this.metaTables.Add(rowType, null);
                        return(null);
                    }
                }
            }

            return(table);
        }
        internal AttributedRootType(AttributedMetaModel model, AttributedMetaTable table, Type type)
            : base(model, table, type, null)
        {
            // check for inheritance and create all other types
            InheritanceMappingAttribute[] inheritanceInfo = (InheritanceMappingAttribute[])type.GetCustomAttributes(typeof(InheritanceMappingAttribute), true);

            if (inheritanceInfo.Length > 0)
            {
                if (this.Discriminator == null)
                {
                    throw Error.NoDiscriminatorFound(type);
                }

                if (!MappingSystem.IsSupportedDiscriminatorType(this.Discriminator.Type))
                {
                    throw Error.DiscriminatorClrTypeNotSupported(this.Discriminator.DeclaringType.Name, this.Discriminator.Name, this.Discriminator.Type);
                }

                this.types = new Dictionary <Type, MetaType>();
                this.types.Add(type, this); // add self
                this.codeMap = new Dictionary <object, MetaType>();

                // initialize inheritance types

                foreach (InheritanceMappingAttribute attr in inheritanceInfo)
                {
                    if (!type.IsAssignableFrom(attr.Type))
                    {
                        throw Error.InheritanceTypeDoesNotDeriveFromRoot(attr.Type, type);
                    }

                    if (attr.Type.IsAbstract)
                    {
                        throw Error.AbstractClassAssignInheritanceDiscriminator(attr.Type);
                    }

                    AttributedMetaType mt = this.CreateInheritedType(type, attr.Type);

                    if (attr.Code == null)
                    {
                        throw Error.InheritanceCodeMayNotBeNull();
                    }

                    if (mt.inheritanceCode != null)
                    {
                        throw Error.InheritanceTypeHasMultipleDiscriminators(attr.Type);
                    }

                    //object codeValue = DBConvert.ChangeType(*/attr.Code/*, this.Discriminator.Type);
                    object codeValue = attr.Code;

                    foreach (object d in codeMap.Keys)
                    {
                        // if the keys are equal, or if they are both strings containing only spaces
                        // they are considered equal

                        if ((codeValue.GetType() == typeof(string) &&
                             ((string)codeValue).Trim().Length == 0 &&
                             d.GetType() == typeof(string) &&
                             ((string)d).Trim().Length == 0) ||
                            object.Equals(d, codeValue))
                        {
                            throw Error.InheritanceCodeUsedForMultipleTypes(codeValue);
                        }
                    }

                    mt.inheritanceCode = codeValue;
                    this.codeMap.Add(codeValue, mt);

                    if (attr.IsDefault)
                    {
                        if (this.InheritanceDefault != null)
                        {
                            throw Error.InheritanceTypeHasMultipleDefaults(type);
                        }

                        this.InheritanceDefault = mt;
                    }
                }

                if (this.InheritanceDefault == null)
                {
                    throw Error.InheritanceHierarchyDoesNotDefineDefault(type);
                }
            }

            if (this.types != null)
            {
                this.InheritanceTypes = this.types.Values.ToList().AsReadOnly();
            }
            else
            {
                this.InheritanceTypes = new MetaType[] { this }.ToList().AsReadOnly();
            }

            Validate();
        }