private void Generate(ScriptWriter scriptWriter, Table table, int count, int nullCount)
        {
            if (scriptWriter == null) throw new ArgumentNullException("scriptWriter");
            if (table == null) throw new ArgumentNullException("table");

            IDictionary<Column, DataGenerator> dataGenerators = _dataGenerators[table];

            // Sort columns
            Logger.Log(LogType.Verbose, value: "Compute column generation order for table " + table.FullName);
            List<KeyValuePair<Column, DataGenerator>> sortedList = new List<KeyValuePair<Column, DataGenerator>>();
            List<KeyValuePair<Column, DataGenerator>> pairs = dataGenerators.ToList();
            while (pairs.Any())
            {
                KeyValuePair<Column, DataGenerator>? addedValue = null;
                foreach (var first in pairs)
                {
                    bool canAdd = true;
                    foreach (var second in pairs)
                    {
                        if (first.Value.CompareTo(second.Value) > 0)
                        {
                            canAdd = false;
                        }
                    }

                    if (canAdd)
                    {
                        addedValue = first;
                        break;
                    }
                }

                if (pairs.Any() && addedValue == null)
                {
                    throw new Exception("Cannot determine genration order.");
                }

                if (addedValue.HasValue)
                {
                    sortedList.Add(addedValue.Value);
                    pairs.Remove(addedValue.Value);
                }
            }

            List<Column> columns = sortedList.Select(dataGenerator => dataGenerator.Key).ToList();
            List<DataGenerator> generators = sortedList.Select(_ => _.Value).ToList();
            var values = GenerateValues(this, columns, generators, count, nullCount);

            // Generate values
            Logger.Log(LogType.Verbose, value: "Begin generating rows for table " + table.FullName);
            scriptWriter.WriteBeginTable(_database, table);

            for (int i = 0; i < count; i++)
            {
                if (i > 0 && BatchStatementCount > 0 && i % BatchStatementCount == 0)
                {
                    scriptWriter.WriteBatchSeparator(_database);
                }

                scriptWriter.WriteBeginRow(_database, table, columns);
                _currentRow = new RowValues(columns, generators);
                bool first = true;
                foreach (var column in columns)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        scriptWriter.WriteValueSeparator(_database);
                    }

                    var enumerator = values[column];
                    if (!enumerator.MoveNext())
                    {
                        throw new Exception("Can't move next.");
                    }

                    CurrentRow.AddValue(column, enumerator.Current);

                    IList<object> generatedValues;
                    if (_generatedValues.TryGetValue(column, out generatedValues))
                    {
                        generatedValues.Add(enumerator.Current);
                    }

                    scriptWriter.WriteValue(_database, column, enumerator.Current);
                }

                scriptWriter.WriteEndRow(_database, table, columns);
            }

            scriptWriter.WriteEndTable(_database, table);
            _currentRow = null;
        }
        public void Generate(ScriptWriter scriptWriter, int count, int nullCount)
        {
            if (scriptWriter == null) throw new ArgumentNullException("scriptWriter");

            _generatedValues.Clear();

            // We need to keep some columns values...
            foreach (var column in _columns)
            {
                foreach (var fk in column.Parent.ForeignKeys)
                {
                    Key pk = fk.ReferencedTable.PrimaryKey;
                    if (pk == null)
                        continue;

                    foreach (var pkColumn in pk.Columns)
                    {
                        if (_columns.Contains(pkColumn) && !_generatedValues.ContainsKey(pkColumn))
                        {
                            _generatedValues.Add(pkColumn, new List<object>());
                        }
                    }
                }
            }

            // Compute generation order
            Logger.Log(LogType.Verbose, value: "Compute table generation order");
            List<Table> tables = new List<Table>();
            var allTables = _dataGenerators.Keys.ToList();
            while (allTables.Any())
            {
                Table addedTable = null;
                foreach (var table in allTables)
                {
                    bool canAdd = true;
                    foreach (var foreignKey in table.ForeignKeys)
                    {
                        if (!tables.Contains(foreignKey.ReferencedTable))
                        {
                            canAdd = false;
                            break;
                        }
                    }

                    if (canAdd)
                    {
                        addedTable = table;
                        break;
                    }
                }

                if (allTables.Any() && addedTable == null)
                {
                    throw new Exception("Cannot determine generation order.");
                }

                tables.Add(addedTable);
                allTables.Remove(addedTable);
            }

            // Generate values
            scriptWriter.WriteHeader(this);

            foreach (var table in tables)
            {
                Generate(scriptWriter, table, count, nullCount);
            }

            scriptWriter.WriteFooter(this);
        }