internal DataTable GetSchemaTable(bool wantUniqueInfo, bool wantDefaultValue)
        {
            CheckClosed();

            DataTable tbl        = new DataTable("SchemaTable");
            DataTable tblIndexes = null;
            DataTable tblIndexColumns;
            DataRow   row;
            string    temp;
            string    strCatalog = "";
            string    strTable   = "";
            string    strColumn  = "";

            tbl.Locale = CultureInfo.InvariantCulture;
            tbl.Columns.Add(SchemaTableColumn.ColumnName, typeof(String));
            tbl.Columns.Add(SchemaTableColumn.ColumnOrdinal, typeof(int));
            tbl.Columns.Add(SchemaTableColumn.ColumnSize, typeof(int));
            tbl.Columns.Add(SchemaTableColumn.NumericPrecision, typeof(short));
            tbl.Columns.Add(SchemaTableColumn.NumericScale, typeof(short));
            tbl.Columns.Add(SchemaTableColumn.IsUnique, typeof(Boolean));
            tbl.Columns.Add(SchemaTableColumn.IsKey, typeof(Boolean));
            tbl.Columns.Add(SchemaTableOptionalColumn.BaseServerName, typeof(string));
            tbl.Columns.Add(SchemaTableOptionalColumn.BaseCatalogName, typeof(String));
            tbl.Columns.Add(SchemaTableColumn.BaseColumnName, typeof(String));
            tbl.Columns.Add(SchemaTableColumn.BaseSchemaName, typeof(String));
            tbl.Columns.Add(SchemaTableColumn.BaseTableName, typeof(String));
            tbl.Columns.Add(SchemaTableColumn.DataType, typeof(Type));
            tbl.Columns.Add(SchemaTableColumn.AllowDBNull, typeof(Boolean));
            tbl.Columns.Add(SchemaTableColumn.ProviderType, typeof(int));
            tbl.Columns.Add(SchemaTableColumn.IsAliased, typeof(Boolean));
            tbl.Columns.Add(SchemaTableColumn.IsExpression, typeof(Boolean));
            tbl.Columns.Add(SchemaTableOptionalColumn.IsAutoIncrement, typeof(Boolean));
            tbl.Columns.Add(SchemaTableOptionalColumn.IsRowVersion, typeof(Boolean));
            tbl.Columns.Add(SchemaTableOptionalColumn.IsHidden, typeof(Boolean));
            tbl.Columns.Add(SchemaTableColumn.IsLong, typeof(Boolean));
            tbl.Columns.Add(SchemaTableOptionalColumn.IsReadOnly, typeof(Boolean));
            tbl.Columns.Add(SchemaTableOptionalColumn.ProviderSpecificDataType, typeof(Type));
            tbl.Columns.Add(SchemaTableOptionalColumn.DefaultValue, typeof(object));
            tbl.Columns.Add("DataTypeName", typeof(string));
            tbl.Columns.Add("CollationType", typeof(string));
            tbl.BeginLoadData();

            for (int n = 0; n < _fieldCount; n++)
            {
                row = tbl.NewRow();

                DbType typ = GetSQLiteType(n).Type;

                // Default settings for the column
                row[SchemaTableColumn.ColumnName]           = GetName(n);
                row[SchemaTableColumn.ColumnOrdinal]        = n;
                row[SchemaTableColumn.ColumnSize]           = SqliteConvert.DbTypeToColumnSize(typ);
                row[SchemaTableColumn.NumericPrecision]     = SqliteConvert.DbTypeToNumericPrecision(typ);
                row[SchemaTableColumn.NumericScale]         = SqliteConvert.DbTypeToNumericScale(typ);
                row[SchemaTableColumn.ProviderType]         = GetSQLiteType(n).Type;
                row[SchemaTableColumn.IsLong]               = false;
                row[SchemaTableColumn.AllowDBNull]          = true;
                row[SchemaTableOptionalColumn.IsReadOnly]   = false;
                row[SchemaTableOptionalColumn.IsRowVersion] = false;
                row[SchemaTableColumn.IsUnique]             = false;
                row[SchemaTableColumn.IsKey] = false;
                row[SchemaTableOptionalColumn.IsAutoIncrement] = false;
                row[SchemaTableColumn.DataType]         = GetFieldType(n);
                row[SchemaTableOptionalColumn.IsHidden] = false;

#if !MONOTOUCH
                strColumn = _command.Connection._sql.ColumnOriginalName(_activeStatement, n);
                if (String.IsNullOrEmpty(strColumn) == false)
                {
                    row[SchemaTableColumn.BaseColumnName] = strColumn;
                }

                row[SchemaTableColumn.IsExpression] = String.IsNullOrEmpty(strColumn);
                row[SchemaTableColumn.IsAliased]    = (String.Compare(GetName(n), strColumn, true, CultureInfo.InvariantCulture) != 0);

                temp = _command.Connection._sql.ColumnTableName(_activeStatement, n);
                if (String.IsNullOrEmpty(temp) == false)
                {
                    row[SchemaTableColumn.BaseTableName] = temp;
                }

                temp = _command.Connection._sql.ColumnDatabaseName(_activeStatement, n);
                if (String.IsNullOrEmpty(temp) == false)
                {
                    row[SchemaTableOptionalColumn.BaseCatalogName] = temp;
                }
#endif

                string dataType = null;
                // If we have a table-bound column, extract the extra information from it
                if (String.IsNullOrEmpty(strColumn) == false)
                {
                    string   collSeq;
                    bool     bNotNull;
                    bool     bPrimaryKey;
                    bool     bAutoIncrement;
                    string[] arSize;

                    // Get the column meta data
                    _command.Connection._sql.ColumnMetaData(
                        (string)row[SchemaTableOptionalColumn.BaseCatalogName],
                        (string)row[SchemaTableColumn.BaseTableName],
                        strColumn,
                        out dataType, out collSeq, out bNotNull, out bPrimaryKey, out bAutoIncrement);

                    if (bNotNull || bPrimaryKey)
                    {
                        row[SchemaTableColumn.AllowDBNull] = false;
                    }

                    row[SchemaTableColumn.IsKey] = bPrimaryKey;
                    row[SchemaTableOptionalColumn.IsAutoIncrement] = bAutoIncrement;
                    row["CollationType"] = collSeq;

                    // For types like varchar(50) and such, extract the size
                    arSize = dataType.Split('(');
                    if (arSize.Length > 1)
                    {
                        dataType = arSize[0];
                        arSize   = arSize[1].Split(')');
                        if (arSize.Length > 1)
                        {
                            arSize = arSize[0].Split(',', '.');
                            if (GetSQLiteType(n).Type == DbType.String || GetSQLiteType(n).Type == DbType.Binary)
                            {
                                row[SchemaTableColumn.ColumnSize] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture);
                            }
                            else
                            {
                                row[SchemaTableColumn.NumericPrecision] = Convert.ToInt32(arSize[0], CultureInfo.InvariantCulture);
                                if (arSize.Length > 1)
                                {
                                    row[SchemaTableColumn.NumericScale] = Convert.ToInt32(arSize[1], CultureInfo.InvariantCulture);
                                }
                            }
                        }
                    }

                    if (wantDefaultValue)
                    {
                        // Determine the default value for the column, which sucks because we have to query the schema for each column
                        using (SqliteCommand cmdTable = new SqliteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].TABLE_INFO([{1}])",
                                                                                        row[SchemaTableOptionalColumn.BaseCatalogName],
                                                                                        row[SchemaTableColumn.BaseTableName]
                                                                                        ), _command.Connection))
                            using (DbDataReader rdTable = cmdTable.ExecuteReader())
                            {
                                // Find the matching column
                                while (rdTable.Read())
                                {
                                    if (String.Compare((string)row[SchemaTableColumn.BaseColumnName], rdTable.GetString(1), true, CultureInfo.InvariantCulture) == 0)
                                    {
                                        if (rdTable.IsDBNull(4) == false)
                                        {
                                            row[SchemaTableOptionalColumn.DefaultValue] = rdTable[4];
                                        }

                                        break;
                                    }
                                }
                            }
                    }

                    // Determine IsUnique properly, which is a pain in the butt!
                    if (wantUniqueInfo)
                    {
                        if ((string)row[SchemaTableOptionalColumn.BaseCatalogName] != strCatalog ||
                            (string)row[SchemaTableColumn.BaseTableName] != strTable)
                        {
                            strCatalog = (string)row[SchemaTableOptionalColumn.BaseCatalogName];
                            strTable   = (string)row[SchemaTableColumn.BaseTableName];

                            tblIndexes = _command.Connection.GetSchema("Indexes", new string[] {
                                (string)row[SchemaTableOptionalColumn.BaseCatalogName],
                                null,
                                (string)row[SchemaTableColumn.BaseTableName],
                                null
                            });
                        }

                        foreach (DataRow rowIndexes in tblIndexes.Rows)
                        {
                            tblIndexColumns = _command.Connection.GetSchema("IndexColumns", new string[] {
                                (string)row[SchemaTableOptionalColumn.BaseCatalogName],
                                null,
                                (string)row[SchemaTableColumn.BaseTableName],
                                (string)rowIndexes["INDEX_NAME"],
                                null
                            });
                            foreach (DataRow rowColumnIndex in tblIndexColumns.Rows)
                            {
                                if (String.Compare((string)rowColumnIndex["COLUMN_NAME"], strColumn, true, CultureInfo.InvariantCulture) == 0)
                                {
                                    if (tblIndexColumns.Rows.Count == 1 && (bool)row[SchemaTableColumn.AllowDBNull] == false)
                                    {
                                        row[SchemaTableColumn.IsUnique] = rowIndexes["UNIQUE"];
                                    }

                                    // If its an integer primary key and the only primary key in the table, then its a rowid alias and is autoincrement
                                    // NOTE:  Currently commented out because this is not always the desired behavior.  For example, a 1:1 relationship with
                                    //        another table, where the other table is autoincrement, but this one is not, and uses the rowid from the other.
                                    //        It is safer to only set Autoincrement on tables where we're SURE the user specified AUTOINCREMENT, even if its a rowid column.

                                    if (tblIndexColumns.Rows.Count == 1 && (bool)rowIndexes["PRIMARY_KEY"] == true && String.IsNullOrEmpty(dataType) == false &&
                                        String.Compare(dataType, "integer", true, CultureInfo.InvariantCulture) == 0)
                                    {
                                        //  row[SchemaTableOptionalColumn.IsAutoIncrement] = true;
                                    }

                                    break;
                                }
                            }
                        }
                    }

                    if (String.IsNullOrEmpty(dataType))
                    {
                        TypeAffinity affin;
                        dataType = _activeStatement._sql.ColumnType(_activeStatement, n, out affin);
                    }

                    if (String.IsNullOrEmpty(dataType) == false)
                    {
                        row["DataTypeName"] = dataType;
                    }
                }
                tbl.Rows.Add(row);
            }

            if (_keyInfo != null)
            {
                _keyInfo.AppendSchemaTable(tbl);
            }

            tbl.AcceptChanges();
            tbl.EndLoadData();

            return(tbl);
        }