private void ExtractExpectedStructure(ref List<Type> types, out List<ExtractedTableMap> tables, out List<Trigger> triggers, out List<Generator> generators, out List<IdentityField> identities, out List<View> views, out List<StoredProcedure> procedures, Connection conn)
        {
            List<View> tviews;
            List<StoredProcedure> tprocs;
            List<Trigger> ttriggers;
            tables = new List<ExtractedTableMap>();
            triggers = new List<Trigger>();
            generators = new List<Generator>();
            identities = new List<IdentityField>();
            views = new List<View>();
            procedures = new List<StoredProcedure>();
            List<Trigger> tmpTriggers = new List<Trigger>();
            List<Generator> tmpGenerators = new List<Generator>();
            List<IdentityField> tmpIdentities = new List<IdentityField>();
            List<StoredProcedure> tmpProcedures = new List<StoredProcedure>();

            Dictionary<string, string> AutoDeleteParentTables = new Dictionary<string, string>();

            for (int x = 0; x < types.Count;x++ )
            {
                Type type = types[x];
                List<Type> ttypes;
                ConnectionPoolManager.GetAdditionalsForTable(_pool, types[x], out tviews, out tprocs, out ttypes,out ttriggers);
                foreach (View vw in tviews)
                {
                    if (vw.RequiredTypes != null)
                    {
                        while (vw.RequiredTypes.Count > 0)
                        {
                            Type tp = vw.RequiredTypes.Dequeue();
                            if (!types.Contains(tp))
                                types.Add(tp);
                        }
                    }
                }
                views.AddRange(tviews);
                procedures.AddRange(tprocs);
                triggers.AddRange(ttriggers);
                foreach (Type t in ttypes)
                {
                    if (!types.Contains(t) && !_createdTypes.Contains(t))
                        types.Add(t);
                }
                ClassViewAttribute cva = _pool[type];
                if (cva!=null)
                {
                    View vw = new View(_pool.Translator.GetViewName(type), cva.Query);
                    views.Add(vw);
                    if (vw.RequiredTypes != null)
                    {
                        while (vw.RequiredTypes.Count > 0)
                        {
                            Type tp = vw.RequiredTypes.Dequeue();
                            if (!types.Contains(tp))
                                types.Add(tp);
                        }
                    }
                }
                else
                {
                    sTable tm = _pool.Mapping[type];
                    ExtractedTableMap etm = new ExtractedTableMap(tm.Name);
                    if (Utility.IsEnum(type))
                    {
                        foreach (sTableField f in tm.Fields)
                            etm.Fields.Add(new ExtractedFieldMap(f.Name, conn.TranslateFieldType(f.Type, f.Length), f.Length, tm.AutoGenField == f.Name, false, tm.AutoGenField == f.Name,f.ComputedCode));
                    }
                    else
                    {
                        Table tbl = (Table)type.GetCustomAttributes(typeof(Table), false)[0];
                        foreach (TableIndex ti in type.GetCustomAttributes(typeof(TableIndex), false))
                        {
                            List<string> tfields = new List<string>();
                            foreach (string str in ti.Fields)
                            {
                                if (str.Contains("."))
                                {
                                    if (!new List<string>(tm.PrimaryKeyProperties).Contains(str.Substring(0, str.IndexOf("."))))
                                        throw new Exception("Unable to create table index for non-table field");
                                    else
                                    {
                                        foreach (sTableField fld in tm[str.Substring(0, str.IndexOf("."))])
                                        {
                                            if (_IsTracedProperty(tm, str.Substring(str.IndexOf(".") + 1), fld, str.Substring(0, str.IndexOf("."))))
                                                tfields.Add(fld.Name);
                                        }
                                    }
                                }
                                else
                                {
                                    sTableField[] flds = tm[str];
                                    if (flds.Length == 0)
                                        tfields.Add(str);
                                    else
                                    {
                                        foreach (sTableField f in flds)
                                            tfields.Add(f.Name);
                                    }
                                }
                            }
                            etm.Indices.Add(new Index(_pool.Translator.GetIndexName(type, ti.Name, conn), tfields.ToArray(), ti.Unique, ti.Ascending));
                        }
                        List<string> pProps = new List<string>(tm.PrimaryKeyProperties);
                        foreach (string prop in tm.Properties)
                        {
                            PropertyInfo pi = type.GetProperty(prop, Utility._BINDING_FLAGS_WITH_INHERITANCE);
                            if (!tm.ArrayProperties.Contains(prop))
                            {
                                sTableRelation? rel = tm.GetRelationForProperty(prop);
                                foreach (sTableField f in tm[prop])
                                {
                                    etm.Fields.Add(new ExtractedFieldMap(f.Name, conn.TranslateFieldType(f.Type, f.Length), f.Length, pProps.Contains(prop), (rel.HasValue ? rel.Value.Nullable : f.Nullable), (tm.AutoGenField != null ? f.Name == tm.AutoGenField : false),f.ComputedCode));
                                    if (rel.HasValue)
                                        etm.ForeignFields.Add(new ForeignRelationMap(type.Name + "_" + prop, f.Name, rel.Value.ExternalTable, f.ExternalField, rel.Value.OnDelete.ToString(), rel.Value.OnUpdate.ToString()));
                                }
                            }
                            else
                            {
                                sTable iMap = _pool.Mapping[type, prop];
                                ExtractedTableMap ietm = new ExtractedTableMap(iMap.Name);
                                string extTable = (_pool.Mapping.IsMappableType(pi.PropertyType.GetElementType()) ? _pool.Mapping[pi.PropertyType.GetElementType()].Name : null);
                                List<string> piKeys = new List<string>(iMap.PrimaryKeyFields);
                                foreach (sTableField f in iMap.Fields)
                                {
                                    ietm.Fields.Add(new ExtractedFieldMap(f.Name, conn.TranslateFieldType(f.Type, f.Length), f.Length, piKeys.Contains(f.Name), false, (iMap.AutoGenField != null ? iMap.AutoGenField == f.Name : false),f.ComputedCode));
                                    if (Utility.StringsEqual("PARENT", f.ClassProperty))
                                        ietm.ForeignFields.Add(new ForeignRelationMap(type.Name + "_" + prop + (_pool.Mapping.IsMappableType(pi.PropertyType.GetElementType()) ? "_intermediate" : ""), f.Name, etm.TableName, f.ExternalField, ForeignField.UpdateDeleteAction.CASCADE.ToString(), ForeignField.UpdateDeleteAction.CASCADE.ToString()));
                                    if (Utility.StringsEqual("CHILD", f.ClassProperty))
                                        ietm.ForeignFields.Add(new ForeignRelationMap(type.Name + "_" + prop, f.Name, extTable, f.ExternalField, ForeignField.UpdateDeleteAction.CASCADE.ToString(), ForeignField.UpdateDeleteAction.CASCADE.ToString()));
                                }
                                tables.Add(ietm);
                            }
                        }
                        if (_pool.Mapping.IsMappableType(type.BaseType))
                        {
                            sTable pMap = _pool.Mapping[type.BaseType];
                            foreach (string str in pMap.PrimaryKeyFields)
                                etm.ForeignFields.Add(new ForeignRelationMap(type.Name + "_parent", str, pMap.Name, str, ForeignField.UpdateDeleteAction.CASCADE.ToString(), ForeignField.UpdateDeleteAction.CASCADE.ToString()));
                            if (tbl.AutoDeleteParent)
                                AutoDeleteParentTables.Add(tm.Name, pMap.Name);
                        }
                        if (_pool.Mapping.HasVersionTable(type))
                        {
                            Org.Reddragonit.Dbpro.Structure.Attributes.VersionField.VersionTypes vt;
                            sTable vtm = _pool.Mapping.GetVersionTable(type, out vt);
                            ExtractedTableMap vetm = new ExtractedTableMap(vtm.Name);
                            List<string> vpkeys = new List<string>(tm.PrimaryKeyFields);
                            foreach (sTableField f in vtm.Fields)
                            {
                                vetm.Fields.Add(new ExtractedFieldMap(f.Name, conn.TranslateFieldType(f.Type, f.Length), f.Length, vpkeys.Contains(f.Name), !vpkeys.Contains(f.Name), vtm.AutoGenField == f.Name,f.ComputedCode));
                                if (vpkeys.Contains(f.Name))
                                    vetm.ForeignFields.Add(new ForeignRelationMap(type.Name + "_version", f.Name, tm.Name, f.Name, ForeignField.UpdateDeleteAction.CASCADE.ToString(), ForeignField.UpdateDeleteAction.CASCADE.ToString()));
                            }
                            triggers.AddRange(conn.GetVersionTableTriggers(vetm, vt));
                            tables.Add(vetm);
                        }
                    }
                    tables.Add(etm);
                    bool keyDifferent = false;
                    foreach (ExtractedTableMap e in _tables)
                    {
                        if (etm.TableName == e.TableName)
                        {
                            foreach (ExtractedFieldMap efm in etm.PrimaryKeys)
                            {
                                bool foundField = false;
                                foreach (ExtractedFieldMap ee in e.PrimaryKeys)
                                {
                                    if (ee.FieldName == efm.FieldName)
                                    {
                                        foundField = true;
                                        if ((ee.PrimaryKey != efm.PrimaryKey) || (ee.PrimaryKey && efm.PrimaryKey && ((ee.Type != efm.Type) || (ee.Size != efm.Size))))
                                            keyDifferent = true;
                                        break;
                                    }
                                }
                                if (!foundField)
                                    keyDifferent = true;
                                if (keyDifferent)
                                    break;
                            }
                            if (keyDifferent)
                                break;
                        }
                    }
                    if (keyDifferent)
                    {
                        foreach (ExtractedTableMap e in _tables)
                        {
                            if (e.RelatedTables.Contains(etm.TableName))
                            {
                                Type t = _pool.Mapping[e.TableName];
                                if (t != null)
                                {
                                    if (!types.Contains(t) && !_createdTypes.Contains(t))
                                        types.Add(t);
                                }
                            }
                        }
                    }
                }
            }
            for(int x=0;x<tables.Count;x++)
            {
                ExtractedTableMap etm = tables[x];
                Logger.LogLine(etm.TableName + ":");
                foreach (ExtractedFieldMap efm in etm.Fields)
                    Logger.LogLine("\t" + efm.FieldName + " - " + efm.PrimaryKey.ToString());
                if (!_pool.Mapping.IsVersionTable(etm.TableName))
                {
                    foreach (ExtractedFieldMap efm in etm.PrimaryKeys)
                    {
                        if (efm.AutoGen)
                        {
                            conn.GetAddAutogen(etm, out tmpIdentities, out tmpGenerators, out tmpTriggers, out tmpProcedures);
                            if (tmpGenerators != null)
                                generators.AddRange(tmpGenerators);
                            if (tmpTriggers != null)
                                triggers.AddRange(tmpTriggers);
                            if (tmpIdentities != null)
                                identities.AddRange(tmpIdentities);
                            if (tmpProcedures != null)
                                procedures.AddRange(tmpProcedures);
                            break;
                        }
                    }
                    if (AutoDeleteParentTables.ContainsKey(etm.TableName))
                    {
                        ExtractedTableMap ptm = new ExtractedTableMap();
                        foreach (ExtractedTableMap m in tables)
                        {
                            if (AutoDeleteParentTables[etm.TableName] == m.TableName)
                            {
                                ptm = m;
                                break;
                            }
                        }
                        if (ptm.TableName == null)
                        {
                            sTable ptbl =  _pool.Mapping[_pool.Mapping[AutoDeleteParentTables[etm.TableName]]];
                            ptm = new ExtractedTableMap(ptbl.Name);
                            List<string> pkeys = new List<string>(ptbl.PrimaryKeyFields);
                            foreach (sTableField f in ptbl.Fields)
                                ptm.Fields.Add(new ExtractedFieldMap(f.Name, conn.TranslateFieldType(f.Type, f.Length), f.Length, pkeys.Contains(f.Name), f.Nullable,f.ComputedCode));
                        }
                        triggers.AddRange(conn.GetDeleteParentTrigger(etm, ptm));
                    }
                }
                if (conn is MsSqlConnection)
                    ((MsSqlConnection)conn).MaskComplicatedRelations(x, ref tables, ref triggers, AutoDeleteParentTables);
            }

            for (int x = 0; x < procedures.Count; x++)
            {
                for (int y = x + 1; y < procedures.Count; y++)
                {
                    if (procedures[x].Equals(procedures[y]))
                    {
                        procedures.RemoveAt(y);
                        y--;
                    }
                }
            }
        }