package sword.langbook3.android.db;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public final class DbInsertQuery {

    private final DbTable _table;
    private final int[] _columns;
    private final DbValue[] _values;

    private DbInsertQuery(DbTable table, int[] columns, DbValue[] values) {
        _table = table;
        _columns = columns;
        _values = values;
    }

    public DbTable getTable() {
        return _table;
    }

    public int getColumnCount() {
        return _columns.length;
    }

    public DbColumn getColumn(int index) {
        return _table.columns().get(_columns[index]);
    }

    public DbValue getValue(int index) {
        return _values[index];
    }

    public static final class Builder {
        private final DbTable _table;
        private final Map<Integer, DbValue> _map = new HashMap<>();

        public Builder(DbTable table) {
            if (table == null) {
                throw new IllegalArgumentException();
            }

            _table = table;
        }

        private DbInsertQuery.Builder put(int column, DbValue value) {
            if (column < 0 || column >= _table.columns().size() || _map.containsKey(column)) {
                throw new IllegalArgumentException();
            }

            _map.put(column, value);
            return this;
        }

        public Builder put(int column, int value) {
            return put(column, new DbIntValue(value));
        }

        public Builder put(int column, String value) {
            return put(column, new DbStringValue(value));
        }

        public DbInsertQuery build() {
            final int size = _map.size();
            final int[] keys = new int[size];

            int i = 0;
            for (int key : _map.keySet()) {
                keys[i++] = key;
            }
            Arrays.sort(keys);

            final DbValue[] values = new DbValue[size];
            for (i = 0; i < size; i++) {
                values[i] = _map.get(keys[i]);
            }

            return new DbInsertQuery(_table, keys, values);
        }
    }
}

@@ -41,69 +41,84 @@
 ort 
-java.util.Arrays;%0Aimport java.util.HashMap;%0Aimport java.util.
+sword.collections.ImmutableIntKeyMap;%0Aimport sword.collections.MutableIntKey
 Map;
@@ -211,51 +211,35 @@
 nal 
-int%5B%5D _columns;%0A    private final 
+ImmutableIntKeyMap%3C
 DbValue
-%5B%5D
+%3E
  _va
@@ -290,32 +290,35 @@
 le, 
-int%5B%5D columns, 
+ImmutableIntKeyMap%3C
 DbValue
-%5B%5D
+%3E
  val
@@ -352,36 +352,8 @@
 le;%0A
-        _columns = columns;%0A
     
@@ -497,22 +497,21 @@
 rn _
-columns.length
+values.size()
 ;%0A  
@@ -599,22 +599,27 @@
 et(_
-columns%5B
+values.keyAt(
 index
-%5D
+)
 );%0A 
@@ -691,15 +691,23 @@
 lues
-%5B
+.valueAt(
 index
-%5D
+)
 ;%0A  
@@ -816,49 +816,65 @@
 al M
-ap%3CInteger, DbValue%3E _map = new HashMap%3C%3E
+utableIntKeyMap%3CDbValue%3E _values = MutableIntKeyMap.empty
 ();%0A
@@ -1194,19 +1194,31 @@
 e() %7C%7C _
-map
+values.keySet()
 .contain
@@ -1218,19 +1218,16 @@
 contains
-Key
 (column)
@@ -1312,19 +1312,22 @@
        _
-map
+values
 .put(col
@@ -1660,402 +1660,8 @@
 ) %7B%0A
-            final int size = _map.size();%0A            final int%5B%5D keys = new int%5Bsize%5D;%0A%0A            int i = 0;%0A            for (int key : _map.keySet()) %7B%0A                keys%5Bi++%5D = key;%0A            %7D%0A            Arrays.sort(keys);%0A%0A            final DbValue%5B%5D values = new DbValue%5Bsize%5D;%0A            for (i = 0; i %3C size; i++) %7B%0A                values%5Bi%5D = _map.get(keys%5Bi%5D);%0A            %7D%0A%0A
     
@@ -1705,20 +1705,29 @@
 le, 
-keys, values
+_values.toImmutable()
 );%0A 

Change implementation for DbInsertQuery