// @Override
        public MutableTable buildTable()
        {
            int tableObservations = getObservationCount();

            // sort column names by copying them to a TreeSet
            HashSet <String> columnNames = new HashSet <String>(_columnBuilders.Keys);  // new TreeSet<String>(_columnBuilders.keySet());

            MutableTable table        = new MutableTable(_tableName);
            int          columnNumber = 0;

            foreach (String columnName in columnNames)
            {
                InferentialColumnBuilder columnBuilder = (InferentialColumnBuilder)getColumnBuilder(columnName);
                MutableColumn            column        = columnBuilder.build();
                column.setTable(table);
                column.setColumnNumber(columnNumber);

                int columnObservations = columnBuilder.getObservationCount();
                if (tableObservations > columnObservations)
                {
                    // there may be nulls - some records does not even contain the
                    // column
                    column.setNullable(true);
                }

                table.addColumn(column);

                columnNumber++;
            }

            return(table);
        }
        // @Override
        public ColumnBuilder getColumnBuilder(String column_name)
        {
            InferentialColumnBuilder column_builder = null;

            if (_columnBuilders.ContainsKey(column_name))
            {
                column_builder = _columnBuilders[column_name];
            }

            if (column_builder == null)
            {
                column_builder = new InferentialColumnBuilder(column_name);
                _columnBuilders.Add(column_name, column_builder);
            }
            return(column_builder);
        } // getColumnBuilder()
        } // constructor

        public void addObservation(Document document)
        {
            _observationCounter.incrementAndGet();
            Dictionary <String, object> values = document.getValues();
            HashSet <KeyValuePair <object, object> > entries = new HashSet <KeyValuePair <object, object> >();

            foreach (String k in values.Keys)
            {
                entries.Add(new KeyValuePair <object, object>(k, values[k]));
            }
            foreach (KeyValuePair <object, object> entry in entries)
            {
                Object key = entry.Key;
                if (key != null)
                {
                    String column = key.ToString();
                    Object value  = entry.Value;
                    InferentialColumnBuilder columnBuilder = (InferentialColumnBuilder)getColumnBuilder(column);
                    columnBuilder.addObservation(value);
                }
            }
        } // addObservation()