Index: src/java/org/apache/lucene/util/CodecUtil.java
===================================================================
--- src/java/org/apache/lucene/util/CodecUtil.java	Fri Jan 22 12:58:35 CET 2010
+++ src/java/org/apache/lucene/util/CodecUtil.java	Fri Jan 22 12:58:35 CET 2010
@@ -0,0 +1,72 @@
+package org.apache.lucene.util;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * <p>NOTE: this class is meant only to be used internally
+ * by Lucene; it's only public so it can be shared across
+ * packages.  This means the API is freely subject to
+ * change, and, the class could be removed entirely, in any
+ * Lucene release.  Use directly at your own risk!
+ */
+
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.index.CorruptIndexException;
+
+import java.io.IOException;
+
+public final class CodecUtil {
+  private final static int CODEC_MAGIC = 0x3fd76c17;
+
+  public static void writeHeader(IndexOutput out, String codec, int version)
+    throws IOException {
+    final long start = out.getFilePointer();
+    out.writeInt(CODEC_MAGIC);
+    out.writeString(codec);
+    out.writeInt(version);
+
+    // We require this so we can easily pre-compute header length
+    if (out.getFilePointer()-start != codec.length()+9) {
+      throw new IllegalArgumentException("codec must be simple ASCII, less than 128 characters in length [got " + codec + "]");
+    }
+  }
+
+  public static int headerLength(String codec) {
+    return 9+codec.length();
+  }
+
+  public static int checkHeader(IndexInput in, String codec, int maxVersion)
+    throws IOException {
+    final int actualHeader = in.readInt();
+    if (actualHeader != CODEC_MAGIC) {
+      throw new CorruptIndexException("codec header mismatch: actual header=" + actualHeader + " vs expected header=" + CODEC_MAGIC);
+    }
+    final String actualCodec = in.readString();
+    if (!actualCodec.equals(codec)) {
+      throw new CorruptIndexException("codec mismatch: actual codec=" + actualCodec + " vs expected codec=" + codec);
+    }
+    final int actualVersion = in.readInt();
+    if (actualVersion > maxVersion) {
+      throw new CorruptIndexException("version " + actualVersion + " is too new (expected <= version " + maxVersion + ")");
+    }
+
+    return actualVersion;
+  }
+}
Index: src/java/org/apache/lucene/util/packed/PackedInts.java
===================================================================
--- src/java/org/apache/lucene/util/packed/PackedInts.java	Mon Mar 01 14:40:00 CET 2010
+++ src/java/org/apache/lucene/util/packed/PackedInts.java	Mon Mar 01 14:40:00 CET 2010
@@ -0,0 +1,394 @@
+package org.apache.lucene.util.packed;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// nocommit -- rename to UnsignedPackedInts?  or pull
+// minValue down
+
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.util.CodecUtil;
+import org.apache.lucene.util.Constants;
+import org.apache.lucene.util.ConsumesRAM;
+
+import java.io.IOException;
+
+/**
+ * Simplistic compression for array of long values, where
+ * each value is >= 0 and <= a specified maximum value.  The
+ * values are stored as packed ints, with each value
+ * consuming a fixed number of bits.
+ * @lucene.internal
+ */
+
+public class PackedInts {
+
+  private final static String CODEC_NAME = "PackedInts";
+  private final static int VERSION_START = 0;
+  private final static int VERSION_CURRENT = 0;
+
+  /**
+   * The priority for selecting the Reader and Writer implementation.
+   * </p><p>
+   * packed:  Pack the bits right after each other.<br />
+   * auto:    Align to 8, 16, 32 or 64 bits on edge-cases to improve speed.
+   * </p><p>
+   * Note: When a more efficient structure (in terms of memory as well as speed)
+   * can be substituted without penalty, this will always be done. Example:
+   * Asking for packed with 8 bits/value will return a direct8, as this is a
+   * less processor-intensive implementation.
+   * </p><p>
+   * Note: 63 bits/value will always be mapped to a direct64, due to the
+   *       problem of stating maxValues > 2^63-1.
+   */
+  public enum STORAGE {packed, auto}
+
+  /**
+   * The size for the underlying blocks for packed structures.
+   * Using 64bit blocks (longs) on a 32bit machine is slower than using 32bit
+   * blocks (ints).
+   */
+  enum BLOCK {bit32(32), bit64(64);
+    private int bits;
+    BLOCK(int bits) {
+      this.bits = bits;
+    }
+
+    public int getBits() {
+      return bits;
+    }
+
+    public static BLOCK getSystemDefault() {
+      return Constants.JRE_IS_64BIT ? bit64 : bit32;
+    }
+  }
+
+  /**
+   * The specific implementation derived from bits/value, STORAGE and BLOCK.
+   */
+  enum IMPLEMENTATION {
+    packed32, packed64, direct8, direct16, direct32, direct64
+  }
+
+  /**
+   * The persistence format used when writing and reading. In the current
+   * implementation only packed is possible.
+   * @see {@link STORAGE}.
+   */
+  enum PERSISTENCE {packed}
+
+  /**
+   * A read-only random access array of positive integers.
+   * @lucene.internal
+   */
+  public static interface Reader extends ConsumesRAM {
+    /**
+     * @param index the position of the wanted value.
+     * @return the value at the stated index.
+     */
+    long get(int index);
+
+    /**
+     * @return the number of bits used to store any given value.
+     *         Note: This does not imply that memory usage is
+     *         {@code bitsPerValue * #values} as implementations are free to
+     *         use non-space-optimal packing of bits.
+     */
+    int getBitsPerValue();
+
+    /**
+     * @return the number of values.
+     */
+    int size();
+  }
+
+  /**
+   * A packed integer array that can be modified.
+   * @lucene.internal
+   */
+  public static interface Mutable extends Reader {
+    /**
+     * Set the value at the given index in the array.
+     * @param index where the value should be positioned.
+     * @param value a value conforming to the constraints set by the array.
+     */
+    void set(int index, long value);
+
+    /**
+     * Sets all values to 0.
+     */
+    
+    void clear();
+  }
+
+  /**
+   * A simple base for Readers that keeps track of valueCount and bitsPerValue.
+   * @lucene.internal
+   */
+  public static abstract class ReaderImpl implements Reader {
+    protected final int bitsPerValue;
+    protected final int valueCount;
+
+    protected ReaderImpl(int valueCount, int bitsPerValue) {
+      this.bitsPerValue = bitsPerValue;
+      this.valueCount = valueCount;
+    }
+
+    public int getBitsPerValue() {
+      return bitsPerValue;
+    }
+    
+    public int size() {
+      return valueCount;
+    }
+
+    public long getMaxValue() { // Convenience method
+      return maxValue(bitsPerValue);
+    }
+  }
+
+  /** A write-once Writer.
+   * @lucene.internal
+   */
+  public static abstract class Writer {
+    protected final IndexOutput out;
+    protected final int bitsPerValue;
+    protected final int valueCount;
+
+    protected Writer(IndexOutput out, int valueCount, int bitsPerValue,
+                     PERSISTENCE persistence) throws IOException {
+      assert bitsPerValue <= 64;
+
+      this.out = out;
+      this.valueCount = valueCount;
+      this.bitsPerValue = bitsPerValue;
+      CodecUtil.writeHeader(out, CODEC_NAME, VERSION_START);
+      out.writeString(persistence.toString());
+      out.writeVInt(bitsPerValue);
+      out.writeVInt(valueCount);
+//      System.out.println("Writer PERSISTENCE: " + persistence + " bitsPerValue: " + bitsPerValue);
+    }
+
+    public abstract void add(long v) throws IOException;
+    public abstract void finish() throws IOException;
+  }
+
+  /**
+   * Retrieve PackedInt data from the IndexInput and return a packed int
+   * structure based on it.
+   * @param in positioned at the beginning of a stored packed int structure.
+   * @return a read only random access capable array of positive integers.
+   * @throws IOException if the structure could not be retrieved.
+   * @lucene.internal
+   */
+  public static Reader getReader(IndexInput in) throws IOException {
+    CodecUtil.checkHeader(in, CODEC_NAME, VERSION_START);
+    String pStr = in.readString();
+    PERSISTENCE persistence = PERSISTENCE.valueOf(pStr);
+    final int bitsPerValue = in.readVInt();
+    final int valueCount = in.readVInt();
+//    final long maxValue = in.readVLong();
+
+    IMPLEMENTATION implementation =
+            getImplementation(persistence, bitsPerValue);
+//    System.out.println("getReader PERSISTENCE: " + persistence + " bitsPerValue: " + bitsPerValue + " IMPLEMENTATION: " + implementation);
+    switch (implementation) {
+      case packed32: return new Packed32(in, valueCount, bitsPerValue);
+      case packed64: return new Packed64(in, valueCount, bitsPerValue);
+      case direct8: return new Direct8(in, valueCount);
+      case direct16: return new Direct16(in, valueCount);
+      case direct32: return new Direct32(in, valueCount);
+      case direct64: return new Direct64(in, valueCount);
+      default: throw new UnsupportedOperationException("Not implemented yet");
+    }
+  }
+
+  /**
+   * Create a packed integer array with the given amount of values initialized
+   * to 0. the valueCount and the bitsPerValue cannot be changed after creation.
+   * All Mutables known by this factory are kept fully in RAM.
+   * @param valueCount   the number of elements.
+   * @param bitsPerValue the number of bits available for any given value.
+   * @param storage the preferred memory-representation.
+   * @return a mutable packed integer array.
+   * @throws java.io.IOException if the Mutable could not be created. With the
+   *         current implementations, this never happens, but the method
+   *         signature allows for future persistence-backed Mutables.
+   * @lucene.internal
+   */
+  public static Mutable getMutable(
+         int valueCount, int bitsPerValue, STORAGE storage) throws IOException {
+    IMPLEMENTATION implementation = getImplementation(bitsPerValue, storage);
+    switch (implementation) {
+      case packed32:  return new Packed32(valueCount, bitsPerValue);
+      case packed64:  return new Packed64(valueCount, bitsPerValue);
+      case direct8:   return new Direct8(valueCount);
+      case direct16:  return new Direct16(valueCount);
+      case direct32:  return new Direct32(valueCount);
+      case direct64:  return new Direct64(valueCount);
+      default: throw new UnsupportedOperationException(
+              implementation + " is not implemented yet");
+    }
+  }
+
+  /**
+   * Create a packed integer array writer for the given number of values at the
+   * given bits/value. Writers append to the given IndexOutput and has very
+   * low memory overhead.
+   * @param out          the destination for the produced bits.
+   * @param valueCount   the number of elements.
+   * @param bitsPerValue the number of bits available for any given value.
+   * @param storage the preferred storage-representation.
+   * @return a Writer ready for receiving values.
+   * @throws IOException if bits could not be written to out.
+   * @lucene.internal
+   */
+  public static Writer getWriter(
+          IndexOutput out, int valueCount, int bitsPerValue,
+          STORAGE storage) throws IOException {
+    return getWriter(
+            out, valueCount, bitsPerValue, storage, BLOCK.getSystemDefault());
+  }
+  static Writer getWriter(
+          IndexOutput out, int valueCount, int bitsPerValue,
+          STORAGE storage, BLOCK block) throws IOException {
+    IMPLEMENTATION implementation = getImplementation(
+            bitsPerValue, storage, block);
+    switch (implementation) {
+      case packed32:
+      case packed64:
+        return new PackedWriter(out, valueCount, bitsPerValue);
+      case direct8:
+        return new PackedWriter(out, valueCount, 8);
+      case direct16:
+        return new PackedWriter(out, valueCount, 16);
+      case direct32:
+        return new PackedWriter(out, valueCount, 32);
+      case direct64:
+        return new PackedWriter(out, valueCount, 64);
+      default: throw new UnsupportedOperationException(
+              implementation + " is not supported");
+    }
+  }
+
+  /**
+   * Derives the optimal IMPLEMENTATION based on the given preferences. Note
+   * that the specified storage does not guarantee that the selected
+   * implementation will be of a specific type, just that the implementations
+   * persistence format is compatible with storage.
+   * @param bitsPerValue the number of bits available for any given value.
+   *                     The returned IMPLEMENTATION will support values of this
+   *                     size or more.
+   * @param storage memory/speed trade-off.
+   * @return the implementation to use.
+   */
+  static IMPLEMENTATION getImplementation(int bitsPerValue, STORAGE storage) {
+    return getImplementation(bitsPerValue, storage, BLOCK.getSystemDefault());
+  }
+  static IMPLEMENTATION getImplementation(
+          int bitsPerValue, STORAGE storage, BLOCK architecture) {
+
+    if (storage == STORAGE.auto) {
+      if (bitsPerValue > 58 || (bitsPerValue < 32 && bitsPerValue > 29)) { // 10% space-waste is ok
+        bitsPerValue = getNextFixedSize(bitsPerValue);
+      }
+    }
+
+    switch (bitsPerValue) { // The safe choices
+      case 8: return IMPLEMENTATION.direct8;
+      case 16: return IMPLEMENTATION.direct16;
+      case 31:
+      case 32: return IMPLEMENTATION.direct32;
+      case 63:
+      case 64: return IMPLEMENTATION.direct64;
+    }
+
+    return bitsPerValue < 32 && architecture == BLOCK.bit32 ?
+            IMPLEMENTATION.packed32 : IMPLEMENTATION.packed64;
+  }
+
+  /**
+   * Derives the optimal IMPLEMENTATION based on the given preferences.
+   * Used for selecting the correct implementation from persistent data.
+   * @param persistence the format of the existing data.
+   * @param bitsPerValue the number of bits available for any given value.
+   * @return the implementation to use.
+   */
+  private static IMPLEMENTATION getImplementation(
+          PERSISTENCE persistence, int bitsPerValue) {
+    return getImplementation(
+            persistence, bitsPerValue, BLOCK.getSystemDefault());
+  }
+  private static IMPLEMENTATION getImplementation(
+            PERSISTENCE persistence, int bitsPerValue, BLOCK architecture) {
+    if (persistence != PERSISTENCE.packed) {
+      throw new IllegalArgumentException(persistence + " is not supported");
+    }
+    switch (bitsPerValue) { // The safe choices
+      case 8: return IMPLEMENTATION.direct8;
+      case 16: return IMPLEMENTATION.direct16;
+      case 31:
+      case 32: return IMPLEMENTATION.direct32;
+      case 63:
+      case 64: return IMPLEMENTATION.direct64;
+    }
+    return bitsPerValue < 32 && architecture == BLOCK.bit32 ?
+            IMPLEMENTATION.packed32 : IMPLEMENTATION.packed64;
+  }
+
+  /** Returns how many bits are required to hold values up
+   *  to and including maxValue
+   * @param maxValue the maximum value tha should be representable.
+   * @return the amount of bits needed to represent values from 0 to maxValue.
+   * @lucene.internal
+   */
+  public static int bitsRequired(long maxValue) {
+    // Very high long values does not translate well to double, so we do an
+    // explicit check for the edge cases
+    if (maxValue > 0x3FFFFFFFFFFFFFFFL) {
+      return 63;
+    } if (maxValue > 0x1FFFFFFFFFFFFFFFL) {
+      return 62;
+    }
+    return (int) Math.ceil(Math.log(1+maxValue)/Math.log(2.0));
+  }
+
+  /**
+   * Calculates the maximum unsigned long that can be expressed with the given
+   * number of bits.
+   * @param bitsPerValue the number of bits available for any given value.
+   * @return the maximum value for the given bits.
+   * @lucene.internal
+   */
+  public static long maxValue(int bitsPerValue) {
+    return bitsPerValue == 64 ? Long.MAX_VALUE : ~(~0L << bitsPerValue);
+  }
+
+  private static int getNextFixedSize(int bits) {
+    if (bits <= 8) {
+      return 8;
+    } else if (bits <= 16) {
+      return 16;
+    } else if (bits <= 32) {
+      return 32;
+    } else {
+      return 64;
+    }
+  }
+
+}
Index: src/java/org/apache/lucene/util/packed/performance.txt
===================================================================
--- src/java/org/apache/lucene/util/packed/performance.txt	Mon Mar 01 13:53:33 CET 2010
+++ src/java/org/apache/lucene/util/packed/performance.txt	Mon Mar 01 13:53:33 CET 2010
@@ -0,0 +1,463 @@
+********************************************************************************
+Run performance tests with
+java -cp lucene-core-3.1-dev.jar org.apache.lucene.util.packed.PackedIntsPerformance
+********************************************************************************
+
+
+********************************************************************************
+testSpeed result by Toke Eskildsen (te@statsbiblioteket.dk) 2010-02-26
+Java 1.6.0_15-b03 64bit Server, default settings, Linux
+Dell Precision M6500: Intel i7 Q 820 @ 1.73GHz, 8 MB cache,
+                      dual-channel PC 1333 RAM
+********************************************************************************
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           1        1000    10000000         129         131         230         224         153         245         226         154         308
+           1     1000000    10000000         216         220         252         221         232         242         220         297         303
+           1    10000000    10000000         353         465         271         265         503         267         260         533         312
+           3        1000    10000000         160         160         260         227         153         253         227         155         322
+           3     1000000    10000000         212         218         262         244         226         258         240         298         349
+           3    10000000    10000000         413         493         327         334         531         326         278         532         327
+           4        1000    10000000         161         159         255         227         153         253         226         155         307
+           4     1000000    10000000         213         217         261         250         225         262         248         296         306
+           4    10000000    10000000         355         459         282         290         499         281         284         534         322
+           7        1000    10000000         160         159         256         226         153         253         232         163         322
+           7     1000000    10000000         212         216         265         260         225         265         257         295         320
+           7    10000000    10000000         358         460         367         407         496         369         382         531         412
+Mean:                                        245         279         274         264         295         272         256         328         325
+
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+           8        1000    10000000         160         159         255         226         153         253         226         154
+           8     1000000    10000000         213         216         266         261         224         266         258         300
+           8    10000000    10000000         362         456         398         406         498         400         402         531
+Mean:                                        245         277         306         297         291         306         295         328
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           9        1000    10000000         159         256         228         152         254         225         154         325
+           9     1000000    10000000         217         267         265         226         268         260         304         320
+           9    10000000    10000000         460         419         458         498         425         433         533         461
+          15        1000    10000000         161         256         228         154         253         227         156         324
+          15     1000000    10000000         217         269         268         227         270         264         296         322
+          15    10000000    10000000         457         491         507         499         493         503         533         519
+Mean:                                        278         326         325         292         327         318         329         378
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+          16        1000    10000000         160         255         227         154         253         227         155
+          16     1000000    10000000         217         269         266         229         270         263         295
+          16    10000000    10000000         454         487         515         491         498         495         528
+Mean:                                        277         337         336         291         340         328         326
+
+bitsPerValue  valueCount    getCount    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+          17        1000    10000000         256         226         153         253         226         155         325
+          17     1000000    10000000         270         277         224         269         269         301         323
+          17    10000000    10000000         499         547         496         501         527         533         530
+          28        1000    10000000         257         227         153         254         227         154         319
+          28     1000000    10000000         273         276         224         274         280         298         325
+          28    10000000    10000000         532         547         497         535         547         530         557
+          31        1000    10000000         256         226         152         253         225         155         345
+          31     1000000    10000000         274         276         225         274         277         301         344
+          31    10000000    10000000         538         553         498         543         549         533         572
+Mean:                                        350         350         291         350         347         328         404
+
+bitsPerValue  valueCount    getCount    Direct32    Packed64   Aligned64    Direct64
+          32        1000    10000000         153         252         226         154
+          32     1000000    10000000         224         274         275         302
+          32    10000000    10000000         492         538         546         527
+Mean:                                        289         354         349         327
+
+bitsPerValue  valueCount    getCount    Packed64   Aligned64    Direct64   Generated
+          33        1000    10000000         253         226         170         331
+          33     1000000    10000000         277         348         324         363
+          33    10000000    10000000         815         578         530         570
+          47        1000    10000000         253         226         154         325
+          47     1000000    10000000         290         356         373         456
+          47    10000000    10000000         557         573         529         585
+          49        1000    10000000         253         225         155         325
+          49     1000000    10000000         413         376         327         365
+          49    10000000    10000000         564         579         528         589
+          63        1000    10000000         251         228         169         327
+          63     1000000    10000000         379         390         350         429
+          63    10000000    10000000         575         578         531         602
+Mean:                                        406         390         345         438
+
+Total execution time: 319 seconds
+
+********************************************************************************
+testSpeed result by Michael McCandless 2010-02-27
+Java 1.6.0_17-b04 64 bit server, CentOS 5.4
+Intel core 2 duo E8400 @ 3 GHz, 6 MB cache
+********************************************************************************
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           1        1000    10000000         240         258         332         355         305         342         351         305         395
+           1     1000000    10000000         303         310         351         368         318         348         365         508         390
+           1    10000000    10000000         577         826         320         319         939         320         315        1006         337
+           3        1000    10000000         255         251         299         284         249         307         282         249         347
+           3     1000000    10000000         258         271         315         311         280         320         305         453         345
+           3    10000000    10000000         578         823         329         337         936         330         331        1003         358
+           4        1000    10000000         260         250         304         283         248         308         282         249         321
+           4     1000000    10000000         257         271         314         310         271         313         306         448         330
+           4    10000000    10000000         578         823         353         351         937         340         351        1003         363
+           7        1000    10000000         261         251         305         284         249         308         282         249         332
+           7     1000000    10000000         258         271         318         314         273         315         310         454         343
+           7    10000000    10000000         580         826         564         638         939         572         579        1006         559
+Mean:                                        367         452         342         346         495         343         338         577         368
+
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+           8        1000    10000000         276         251         304         284         249         308         282         249
+           8     1000000    10000000         257         271         315         314         274         315         309         459
+           8    10000000    10000000         582         826         635         638         939         645         640        1006
+Mean:                                        371         449         418         412         487         422         410         571
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           9        1000    10000000         251         305         284         251         308         282         249         335
+           9     1000000    10000000         271         319         320         274         319         313         454         349
+           9    10000000    10000000         826         687         761         939         696         701        1006         677
+          15        1000    10000000         251         304         284         249         308         281         249         335
+          15     1000000    10000000         271         326         325         273         324         317         452         352
+          15    10000000    10000000         824         856         883         937         865         886        1004         836
+Mean:                                        449         466         476         487         470         463         569         480
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+          16        1000    10000000         251         311         284         249         308         281         249
+          16     1000000    10000000         271         325         325         274         324         319         457
+          16    10000000    10000000         826         874         885         939         884         890        1007
+Mean:                                        449         503         498         487         505         496         571
+
+bitsPerValue  valueCount    getCount    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+          17        1000    10000000         312         291         249         311         300         258         335
+          17     1000000    10000000         326         314         272         324         326         454         360
+          17    10000000    10000000         888         982         938         897         951        1005         866
+          28        1000    10000000         304         291         249         308         281         249         330
+          28     1000000    10000000         331         315         278         332         331         550         353
+          28    10000000    10000000         979         986         940         986        1016        1006         968
+          31        1000    10000000         304         291         263         308         281         249         338
+          31     1000000    10000000         334         315         272         331         334         545         363
+          31    10000000    10000000         991         985         939         999        1016        1006         975
+Mean:                                        529         530         488         532         537         591         543
+
+bitsPerValue  valueCount    getCount    Direct32    Packed64   Aligned64    Direct64
+          32        1000    10000000         249         308         281         249
+          32     1000000    10000000         276         332         336         454
+          32    10000000    10000000        1032         998        1016        1006
+Mean:                                        519         546         544         569
+
+bitsPerValue  valueCount    getCount    Packed64   Aligned64    Direct64   Generated
+          33        1000    10000000         308         286         249         338
+          33     1000000    10000000         335         497         462         375
+          33    10000000    10000000        1006        1054        1006         977
+          47        1000    10000000         308         291         249         339
+          47     1000000    10000000         396         497         457         416
+          47    10000000    10000000        1037        1049        1003        1037
+          49        1000    10000000         307         285         248         339
+          49     1000000    10000000         405         496         457         426
+          49    10000000    10000000        1042        1052        1005        1042
+          63        1000    10000000         307         285         248         346
+          63     1000000    10000000         516         508         447         539
+          63    10000000    10000000        1064        1053        1007        1073
+Mean:                                        585         612         569         603
+
+Total execution time: 474 seconds
+
+********************************************************************************
+testSpeed result by Toke Eskildsen (te@statsbiblioteket.dk) 2010-02-26
+Java 1.6.0_15-b03 64bit Server, default settings, Linux
+Server ps3: Intel Xeon L5420 @ 2.50GHz, 6 MB cache
+********************************************************************************
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           1        1000    10000000         361         358         483         540         436         502         521         436         536
+           1     1000000    10000000         411         419         473         550         540         477         545         926         516
+           1    10000000    10000000         935        1137         404         453        1244         403         444        1309         435
+           3        1000    10000000         333         330         394         402         334         390         389         334         458
+           3     1000000    10000000         344         403         401         442         645         398         431         837         431
+           3    10000000    10000000         936        1136         493         593        1244         488         557        1308         504
+           4        1000    10000000         333         328         394         392         334         401         393         334         445
+           4     1000000    10000000         334         354         395         442         444         399         434         836         428
+           4    10000000    10000000         934        1136         638         707        1244         650         699        1309         642
+           7        1000    10000000         337         328         394         411         334         390         389         334         457
+           7     1000000    10000000         334         355         396         444         455         403         434         835         433
+           7    10000000    10000000         935        1137        1016        1076        1245         965        1017        1315         939
+Mean:                                        543         618         490         537         708         488         521         842         518
+
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+           8        1000    10000000         333         330         394         392         334         391         389         334
+           8     1000000    10000000         333         353         399         444         449         397         435         835
+           8    10000000    10000000         934        1136        1008        1074        1244        1021        1070        1309
+Mean:                                        533         606         600         636         675         603         631         826
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           9        1000    10000000         329         472         392         334         391         389         334         455
+           9     1000000    10000000         355         401         451         465         492         438         835         440
+           9    10000000    10000000        1136        1052        1179        1243        1066        1122        1311        1035
+          15        1000    10000000         328         407         392         334         409         389         334         458
+          15     1000000    10000000         355         410         460         452         410         453         835         444
+          15    10000000    10000000        1136        1195        1281        1244        1208        1281        1310        1164
+Mean:                                        606         656         692         678         662         678         826         666
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+          16        1000    10000000         328         408         392         334         391         389         334
+          16     1000000    10000000         354         411         459         456         414         453         836
+          16    10000000    10000000        1137        1207        1282        1244        1221        1274        1308
+Mean:                                        606         675         711         678         675         705         826
+
+bitsPerValue  valueCount    getCount    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+          17        1000    10000000         394         392         334         391         389         334         457
+          17     1000000    10000000         412         579         454         413         465         835         448
+          17    10000000    10000000        1219        1390        1244        1233        1334        1309        1188
+          28        1000    10000000         394         392         334         391         389         334         456
+          28     1000000    10000000         487         566         456         469         583         837         481
+          28    10000000    10000000        1295        1383        1244        1307        1391        1309        1274
+          31        1000    10000000         394         392         334         390         389         334         458
+          31     1000000    10000000         519         567         465         508         581         837         530
+          31    10000000    10000000        1306        1382        1243        1318        1389        1309        1268
+Mean:                                        713         782         678         713         767         826         728
+
+bitsPerValue  valueCount    getCount    Direct32    Packed64   Aligned64    Direct64
+          32        1000    10000000         334         390         389         334
+          32     1000000    10000000         391         458         507         835
+          32    10000000    10000000        1243        1322        1400        1308
+Mean:                                        656         723         765         825
+
+bitsPerValue  valueCount    getCount    Packed64   Aligned64    Direct64   Generated
+          33        1000    10000000         390         389         334         460
+          33     1000000    10000000         526         965         834         579
+          33    10000000    10000000        1322        1453        1308        1277
+          47        1000    10000000         390         389         334         462
+          47     1000000    10000000         746         963         835         758
+          47    10000000    10000000        1354        1454        1308        1337
+          49        1000    10000000         391         391         334         462
+          49     1000000    10000000         771         961         835         780
+          49    10000000    10000000        1358        1454        1309        1341
+          63        1000    10000000         390         389         334         463
+          63     1000000    10000000         912         966         838         957
+          63    10000000    10000000        1428        1457        1308        1350
+Mean:                                        831         935         825         852
+
+Total execution time: 675 seconds
+
+********************************************************************************
+testSpeed result by Toke Eskildsen (te@statsbiblioteket.dk) 2010-02-28
+Java 1.6.0_? 32bit Workstation, default settings, Windows XP
+Server alma: AMD Athlon X2 4850e @ 2.5GHz, 2*512 KB cache
+********************************************************************************
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           1        1000    10000000         551         603         735         797         618         867         880         602         881
+           1     1000000    10000000        1024        1258         737         840        1425         884         893        1541         895
+           1    10000000    10000000        1470        1606        1236        1299        1695        1396        1390        1893        1391
+           3        1000    10000000         614         614         724         812         614         860         870         618         875
+           3     1000000    10000000        1020        1250         766         846        1421         926         941        1532         945
+           3    10000000    10000000        1536        1608        1519        1616        1698        1677        1686        1896        1681
+           4        1000    10000000         613         614         732         811         614         858         870         620         746
+           4     1000000    10000000        1029        1248         840         900        1422         991         994        1531         856
+           4    10000000    10000000        1539        1608        1567        1633        1700        1735        1731        1893        1603
+           7        1000    10000000         596         598         716         800         600         848         852         603         883
+           7     1000000    10000000        1012        1242        1073        1229        1409        1246        1249        1526        1246
+           7    10000000    10000000        1531        1599        1627        1709        1685        1794        1793        1883        1807
+Mean:                                       1044        1154        1022        1107        1241        1173        1179        1344        1150
+
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+           8        1000    10000000         609         612         731         810         597         859         868         616
+           8     1000000    10000000        1020        1245        1138        1206        1407        1287        1283        1525
+           8    10000000    10000000        1529        1599        1644        1707        1684        1811        1805        1883
+Mean:                                       1052        1152        1171        1241        1229        1319        1318        1341
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           9        1000    10000000         612         729         795         612         865         866         603         881
+           9     1000000    10000000        1238        1185        1308        1408        1346        1333        1524        1357
+           9    10000000    10000000        1597        1658        1734        1687        1831        1818        1882        1838
+          15        1000    10000000         595         706         791         595         854         854         602         867
+          15     1000000    10000000        1241        1349        1424        1409        1520        1512        1525        1522
+          15    10000000    10000000        1600        1706        1773        1684        1891        1873        1885        1895
+Mean:                                       1147        1222        1304        1232        1384        1376        1336        1393
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+          16        1000    10000000         612         715         810         612         863         851         615
+          16     1000000    10000000        1240        1355        1423        1412        1516        1512        1525
+          16    10000000    10000000        1596        1713        1774        1686        1879        1874        1888
+Mean:                                       1149        1261        1335        1236        1419        1412        1342
+
+bitsPerValue  valueCount    getCount    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+          17        1000    10000000         707         810         611         856         843         615         867
+          17     1000000    10000000        1370        1588        1409        1550        1585        1528        1563
+          17    10000000    10000000        1718        1868        1685        1898        1907        1889        1911
+          28        1000    10000000         730         810         611         867         867         615         763
+          28     1000000    10000000        1499        1587        1408        1671        1674        1518        1575
+          28    10000000    10000000        1789        1860        1686        1960        1963        1886        1876
+          31        1000    10000000         728         809         612         841         867         615         877
+          31     1000000    10000000        1517        1587        1406        1681        1681        1527        1739
+          31    10000000    10000000        1804        1869        1689        1965        1964        1883        2016
+Mean:                                       1318        1420        1235        1476        1483        1341        1465
+
+bitsPerValue  valueCount    getCount    Direct32    Packed64   Aligned64    Direct64
+          32        1000    10000000         613         842         851         615
+          32     1000000    10000000        1410        1689        1682        1520
+          32    10000000    10000000        1686        1970        1968        1887
+Mean:                                       1236        1500        1500        1340
+
+bitsPerValue  valueCount    getCount    Packed64   Aligned64    Direct64   Generated
+          33        1000    10000000         839         830         602         894
+          33     1000000    10000000        1684        1732        1524        1752
+          33    10000000    10000000        1974        2104        1887        2028
+          47        1000    10000000         882         814         602         906
+          47     1000000    10000000        1776        1734        1526        1828
+          47    10000000    10000000        2099        2100        1886        2156
+          49        1000    10000000         891         831         616         907
+          49     1000000    10000000        1772        1733        1523        1841
+          49    10000000    10000000        2126        2100        1886        2172
+          63        1000    10000000         858         831         615         896
+          63     1000000    10000000        1780        1736        1527        1886
+          63    10000000    10000000        2164        2109        1887        2265
+Mean:                                       1570        1554        1340        1627
+
+Total execution time: 1284 seconds
+
+
+********************************************************************************
+testSpeed result by Toke Eskildsen (te@statsbiblioteket.dk) 2010-02-28
+Java 1.6.0_? 32bit Workstation, default settings, Windows XP
+Laptop te-xp: Intel T2400 Core Duo @ 1.8GHz, 2 MB cache, 667 MHz bus
+********************************************************************************
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           1        1000    10000000         769         800         947         962         801        1080        1106         793        1170
+           1     1000000    10000000         879         899         926         974        1379        1070        1114        1651        1149
+           1    10000000    10000000        1668        1829         950         969        1896        1100        1134        1923        1215
+           3        1000    10000000         786         786         941         937         785        1078        1083         784        1188
+           3     1000000    10000000         787         871         927         951        1348        1071        1106        1634        1164
+           3    10000000    10000000        1699        1833        1485        1532        1896        1756        1639        1905        1691
+           4        1000    10000000         787         786         940         938         787        1074        1083         785        1024
+           4     1000000    10000000         783         848         927         951        1352        1071        1110        1634        1018
+           4    10000000    10000000        1699        1825        1632        1642        1896        1891        1795        1903        1711
+           7        1000    10000000         788         787         941         943         787        1085        1083         784        1193
+           7     1000000    10000000         784         848         936         957        1363        1096        1121        1637        1175
+           7    10000000    10000000        1707        1826        1818        1883        1902        2082        1986        1906        2036
+Mean:                                       1094        1161        1114        1136        1349        1287        1280        1444        1311
+
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+           8        1000    10000000         786         787         943         939         788        1075        1084         783
+           8     1000000    10000000         786         874         936         953        1350        1106        1122        1640
+           8    10000000    10000000        1703        1832        1858        1873        1900        2100        2020        1917
+Mean:                                       1091        1164        1245        1255        1346        1427        1408        1446
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           9        1000    10000000         788         941        1014         787        1088        1083         784        1196
+           9     1000000    10000000         881         947         967        1353        1105        1115        1626        1187
+           9    10000000    10000000        1837        1889        1947        1901        2133        2031        1916        2113
+          15        1000    10000000         793         942         938         787        1095        1084         783        1196
+          15     1000000    10000000         870        1008        1049        1354        1166        1219        1640        1233
+          15    10000000    10000000        1825        2009        2010        1898        2228        2133        1920        2220
+Mean:                                       1165        1289        1320        1346        1469        1444        1444        1524
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+          16        1000    10000000         787         941         939         787        1074        1084         784
+          16     1000000    10000000         850        1000        1074        1351        1180        1224        1634
+          16    10000000    10000000        1835        1984        2001        1901        2205        2166        1919
+Mean:                                       1157        1308        1338        1346        1486        1491        1445
+
+bitsPerValue  valueCount    getCount    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+          17        1000    10000000         941         937         786        1094        1073         785        1198
+          17     1000000    10000000        1069        1521        1348        1262        1397        1625        1296
+          17    10000000    10000000        1997        2078        1895        2238        2147        1925        2245
+          28        1000    10000000         940         938         787        1192        1085         783        1060
+          28     1000000    10000000        1423        1520        1364        1734        1719        1635        1592
+          28    10000000    10000000        2035        2075        1899        2284        2205        1920        2197
+          31        1000    10000000         963         974         789        1071        1085         783        1207
+          31     1000000    10000000        1506        1515        1337        1763        1705        1636        1789
+          31    10000000    10000000        2054        2068        1892        2296        2206        1924        2345
+Mean:                                       1436        1514        1344        1659        1624        1446        1658
+
+bitsPerValue  valueCount    getCount    Direct32    Packed64   Aligned64    Direct64
+          32        1000    10000000         790        1074        1084         785
+          32     1000000    10000000        1352        1781        1678        1638
+          32    10000000    10000000        1898        2279        2206        1918
+Mean:                                       1346        1711        1656        1447
+
+bitsPerValue  valueCount    getCount    Packed64   Aligned64    Direct64   Generated
+          33        1000    10000000        1070        1002         784        1208
+          33     1000000    10000000        1795        1854        1637        1840
+          33    10000000    10000000        2313        2164        1905        2360
+          47        1000    10000000        1136        1002         785        1220
+          47     1000000    10000000        2010        1862        1624        2036
+          47    10000000    10000000        2422        2169        1916        2486
+          49        1000    10000000        1119        1001         784        1222
+          49     1000000    10000000        2016        1856        1636        2074
+          49    10000000    10000000        2397        2171        1926        2498
+          63        1000    10000000        1074        1003         783        1226
+          63     1000000    10000000        2049        1858        1642        2192
+          63    10000000    10000000        2426        2158        1921        2595
+Mean:                                       1818        1675        1445        1913
+
+Total execution time: 1381 seconds
+
+********************************************************************************
+testSpeed result by Toke Eskildsen (te@statsbiblioteket.dk) 2010-02-26
+Java 1.6.0_07-b06 64bit Server, default settings, Linux
+Server debit: Intel Xeon MP CPU @ 3.16GHz, 1 MB cache
+********************************************************************************
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           1        1000    10000000         427         430         498         753         470         545         746         470         620
+           1     1000000    10000000         818        1597         556         751        2069         575         747        2348         627
+           1    10000000    10000000        2354        2542        1196        1378        2544        1177        1315        2718        1192
+           3        1000    10000000         469         468         527         733         482         534         725         495         633
+           3     1000000    10000000         929        1571         594         789        2026         627         778        2287         646
+           3    10000000    10000000        2424        2534        2247        2339        2559        2360        2320        2720        2139
+           4        1000    10000000         469         469         528         734         483         534         725         495         620
+           4     1000000    10000000         876        1593         630         807        2027         653         812        2277         681
+           4    10000000    10000000        2419        2513        2367        2441        2557        2511        2451        2700        2301
+           7        1000    10000000         470         469         530         734         483         534         726         495         634
+           7     1000000    10000000         855        1590         822        1228        2024         886         997        2293         816
+           7    10000000    10000000        2416        2524        2561        2647        2557        2721        2641        2712        2464
+Mean:                                       1243        1525        1088        1277        1690        1138        1248        1834        1114
+
+bitsPerValue  valueCount    getCount     Direct8    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+           8        1000    10000000         469         470         527         733         494         535         726         496
+           8     1000000    10000000         795        1569         958        1112        2042         951        1061        2299
+           8    10000000    10000000        2417        2505        2608        2655        2579        2768        2672        2718
+Mean:                                       1227        1514        1364        1500        1705        1418        1486        1837
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+           9        1000    10000000         470         529         736         486         533         728         493         633
+           9     1000000    10000000        1587        1029        1409        2026        1205        1239        2277        1102
+           9    10000000    10000000        2519        2637        2723        2570        2776        2693        2723        2517
+          15        1000    10000000         468         527         736         485         534         728         496         631
+          15     1000000    10000000        1606        1675        1835        2023        1746        1813        2278        1602
+          15    10000000    10000000        2522        2734        2773        2557        2867        2770        2748        2603
+Mean:                                       1528        1521        1702        1691        1610        1661        1835        1514
+
+bitsPerValue  valueCount    getCount    Direct16    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64
+          16        1000    10000000         469         528         734         484         534         725         496
+          16     1000000    10000000        1598        1706        1859        2040        1804        1853        2297
+          16    10000000    10000000        2519        2734        2762        2556        2881        2775        2736
+Mean:                                       1528        1656        1785        1693        1739        1784        1843
+
+bitsPerValue  valueCount    getCount    Packed32   Aligned32    Direct32    Packed64   Aligned64    Direct64   Generated
+          17        1000    10000000         528         735         483         535         725         489         632
+          17     1000000    10000000        1800        2347        2038        1886        2088        2297        1738
+          17    10000000    10000000        2728        2860        2570        2903        2814        2708        2620
+          28        1000    10000000         528         734         484         535         724         493         636
+          28     1000000    10000000        2193        2326        2042        2306        2321        2284        2147
+          28    10000000    10000000        2782        2874        2539        2936        2873        2705        2716
+          31        1000    10000000         529         734         482         534         725         487         635
+          31     1000000    10000000        2260        2327        2023        2379        2334        2277        2188
+          31    10000000    10000000        2811        2874        2539        2966        2859        2701        2733
+Mean:                                       1795        1979        1688        1886        1940        1826        1782
+
+bitsPerValue  valueCount    getCount    Direct32    Packed64   Aligned64    Direct64
+          32        1000    10000000         484         536         726         490
+          32     1000000    10000000        2022        2386        2324        2278
+          32    10000000    10000000        2554        2981        2877        2721
+Mean:                                       1686        1967        1975        1829
+
+bitsPerValue  valueCount    getCount    Packed64   Aligned64    Direct64   Generated
+          33        1000    10000000         534         724         494         639
+          33     1000000    10000000        2401        2601        2294        2201
+          33    10000000    10000000        2980        3042        2729        2758
+          47        1000    10000000         534         725         494         649
+          47     1000000    10000000        2602        2614        2310        2403
+          47    10000000    10000000        3081        3029        2742        2882
+          49        1000    10000000         533         724         494         649
+          49     1000000    10000000        2618        2609        2292        2399
+          49    10000000    10000000        3085        3052        2742        2888
+          63        1000    10000000         537         726         494         639
+          63     1000000    10000000        2695        2604        2289        2478
+          63    10000000    10000000        3148        3069        2696        2984
+Mean:                                       2062        2126        1839        1964
+
+Total execution time: 1607 seconds
Index: src/java/org/apache/lucene/util/ConsumesRAM.java
===================================================================
--- src/java/org/apache/lucene/util/ConsumesRAM.java	Fri Jan 22 12:58:35 CET 2010
+++ src/java/org/apache/lucene/util/ConsumesRAM.java	Fri Jan 22 12:58:35 CET 2010
@@ -0,0 +1,22 @@
+package org.apache.lucene.util;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public interface ConsumesRAM {
+  public long ramBytesUsed();
+}
Index: src/java/org/apache/lucene/util/packed/Aligned64.java
===================================================================
--- src/java/org/apache/lucene/util/packed/Aligned64.java	Fri Feb 26 13:28:17 CET 2010
+++ src/java/org/apache/lucene/util/packed/Aligned64.java	Fri Feb 26 13:28:17 CET 2010
@@ -0,0 +1,190 @@
+package org.apache.lucene.util.packed;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.util.RamUsageEstimator;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Medium space and speed trade off. No values crosses block boundaries.
+ * </p><p>
+ * The implementation strives to avoid conditionals and expensive operations,
+ * sacrificing code clarity to achieve better performance.
+ * </p><p>
+ * Space is optimally used within the boundaries of alignment, e.g.
+ * 7 bits/value fits 7 values/block for 64 bit.
+ * Bits are packed left-aligned to be bit pattern compatible with other bit
+ * array implementations where possible.
+ */
+class Aligned64 extends PackedInts.ReaderImpl
+        implements PackedInts.Mutable {
+  static final int BLOCK_SIZE = 64; // 32 = int, 64 = long
+
+  private static final int ENTRY_SIZE = BLOCK_SIZE + 1;
+
+  /*
+   * A value is always positioned inside a single block, requiring a
+   * shift right to position the bits and a mask to extract them.
+  */
+  private static final int[][] SHIFTS = new int[ENTRY_SIZE][ENTRY_SIZE];
+  private static final long[] READ_MASKS = new long[ENTRY_SIZE];
+
+  static { // Generate shifts
+      for (int elementBits = 1 ; elementBits <= BLOCK_SIZE ; elementBits++) {
+          int[] currentShifts = SHIFTS[elementBits];
+          for (int bitPos = 0 ; bitPos < BLOCK_SIZE ; bitPos++) {
+              currentShifts[bitPos] = BLOCK_SIZE - elementBits - bitPos ;
+//            System.out.println("elementBits=" + elementBits + ", bitPos=" + bitPos + ", shift=" + currentShifts[bitPos]);
+              READ_MASKS[elementBits]  = ~(~0L << elementBits);
+          }
+      }
+  }
+
+  /*
+   * Setting a value requires clearing the destination bits with a mask, then
+   * shifting the value to the left and or'ing the two numbers.
+  */
+  private static final long[][] WRITE_MASKS = new long[ENTRY_SIZE][ENTRY_SIZE];
+  static {
+      for (int elementBits = 1 ; elementBits <= BLOCK_SIZE ; elementBits++) {
+          long elementPosMask = ~(~0L << elementBits);
+          int[] currentShifts = SHIFTS[elementBits];
+          long[] currentMasks = WRITE_MASKS[elementBits];
+          for (int bitPos = 0 ; bitPos < BLOCK_SIZE ; bitPos++) {
+              currentMasks[bitPos] = ~(elementPosMask << currentShifts[bitPos]);
+          }
+      }
+  }
+
+  /* The bits */
+  private long[] blocks;
+
+  /* Cached values */
+  private int valuesPerBlock;
+  private int[] shifts;
+  private long readMask;
+  private long[] writeMasks;
+
+  /**
+   * Creates an array with the internal structures adjusted for the given
+   * limits and initialized to 0.
+   * @param valueCount   the number of values.
+   * @param bitsPerValue the number of bits available for any given value.
+   */
+  public Aligned64(int valueCount, int bitsPerValue) {
+    super(valueCount, bitsPerValue);
+    blocks = new long[size(valueCount, bitsPerValue)];
+    updateCached();
+  }
+
+  private static int size(int valueCount, int bitsPerValue) {
+    int valuesPerBlock = BLOCK_SIZE / bitsPerValue;
+    return valueCount == 0 ? 0 : (valueCount-1) / valuesPerBlock + 1;
+  }
+
+  /**
+   * Creates an array with content retrieved from the given IndexInput.
+   * @param in       an IndexInput, positioned at the start of Packed64-content.
+   * @param valueCount  the number of elements.
+   * @param bitsPerValue the number of bits available for any given value.
+   * @throws java.io.IOException if the values for the backing array could not
+   *                             be retrieved.
+   */
+  public Aligned64(IndexInput in, int valueCount, int bitsPerValue)
+                                                            throws IOException {
+    super(valueCount, bitsPerValue);
+    int size = size(valueCount, bitsPerValue);
+    blocks = new long[size];
+    for(int i = 0 ; i < size ; i++) {
+      blocks[i] = in.readLong();
+//        System.out.println("Reading  @bit64: " + Long.toBinaryString((blocks[i])) + " (" + blocks[i] + ")");
+    }
+    in.readLong(); // The extra long if for packed-compatibility
+    updateCached();
+  }
+
+
+  /**
+   * Creates an array backed by the given blocks.
+   * </p><p>
+   * Note: The blocks are used directly, so changes to the given block will
+   * affect the Packed64-structure.
+   * @param blocks     used as the internal backing array.
+   * @param valueCount the number of values.
+   * @param bitsPerValue the number of bits available for any given value.
+   */
+  public Aligned64(long[] blocks, int valueCount, int bitsPerValue) {
+    // TODO: Check that blocks.length is sufficient for holding length values
+    super(valueCount, bitsPerValue);
+    this.blocks = blocks;
+    updateCached();
+  }
+
+  private void updateCached() {
+    valuesPerBlock = BLOCK_SIZE / bitsPerValue;
+    shifts = SHIFTS[bitsPerValue];
+    readMask = READ_MASKS[bitsPerValue];
+    writeMasks = WRITE_MASKS[bitsPerValue];
+  }
+
+  /**
+   * @param index the position of the value.
+   * @return the value at the given index.
+   */
+  public long get(final int index) {
+    final int blockPos = index / valuesPerBlock;
+    final int bitPos = (index - (blockPos * valuesPerBlock)) * bitsPerValue;
+
+    return (blocks[blockPos] >>> shifts[bitPos]) & readMask;
+  }
+
+  public void set(final int index, final long value) {
+    final int blockPos = index / valuesPerBlock;
+    final int bitPos = (index - (blockPos * valuesPerBlock)) * bitsPerValue;
+
+    blocks[blockPos] = (blocks[blockPos] & writeMasks[bitPos])
+            | (value << shifts[bitPos]);
+  }
+
+  public void clear() {
+    Arrays.fill(blocks, 0);
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER
+            + blocks.length * RamUsageEstimator.NUM_BYTES_INT;
+  }
+
+  public String toString() {
+    return "Aligned64(" + valueCount + " values at " 
+            + bitsPerValue + " bits/value)";
+  }
+
+  /**
+   * The backing array contains the bits for the values in this structure.
+   * The array is returned directly, so any changes will be reflected both ways.
+   * Expert use only.
+   * @return the backing array.
+   */
+  long[] getBackingArray() {
+    return blocks;
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/packed/AlignedWriter.java
===================================================================
--- src/java/org/apache/lucene/util/packed/AlignedWriter.java	Mon Mar 01 15:04:54 CET 2010
+++ src/java/org/apache/lucene/util/packed/AlignedWriter.java	Mon Mar 01 15:04:54 CET 2010
@@ -0,0 +1,117 @@
+package org.apache.lucene.util.packed;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.store.IndexOutput;
+
+import java.io.IOException;
+
+// Packs high order byte first, to match
+// IndexOutput.writeInt/Long/Short byte order
+
+/**
+ * Generic writer for block-aligned values: Bits for values are stored so
+ * that block-boundaries are never crossed. For some number of bits, this means
+ * wasted space in the blocks.
+ * </p><p>
+ * The bits for values are stored left-aligned in the blocks, in order to be
+ * bit-pattern compatible with byte, short, int and long-backed implementations
+ * as well as packed for 1, 2, 4, 8, 16, 32 and 64 bits/value.
+ */
+class AlignedWriter extends PackedInts.Writer {
+  private final PackedInts.BLOCK blockPref;
+  private long pending = 0;
+  private int pendingBitPos = 0;
+  private int written = 0;
+  private long flushedInts = 0;
+
+  public AlignedWriter(IndexOutput out, int valueCount,
+                      int bitsPerValue, PackedInts.BLOCK blockPref)
+                                                            throws IOException {
+    super(out, valueCount, bitsPerValue, PackedInts.PERSISTENCE.packed);
+    // IMPORTANT: If this class is to be enabled, the super below should be used
+/*    super(out, valueCount, bitsPerValue,
+            blockPref == PackedInts.BLOCK.bit32 ?
+            PackedInts.PERSISTENCE.aligned32 :  
+            PackedInts.PERSISTENCE.aligned64);*/
+    this.blockPref = blockPref;
+  }
+
+  @Override
+  public void add(long value) throws IOException {
+//    System.out.println("Adding " + value + " to " + this);
+
+    // TODO: Consider caching maxValue and bits/block
+    assert value <= PackedInts.maxValue(bitsPerValue) : "value=" + value
+            + " maxValue=" + PackedInts.maxValue(bitsPerValue);
+    assert value >= 0;
+    assert written <= valueCount : "The number of values to write has been " +
+            "exceeded, expected number of values: " + valueCount;
+    pending |= value << (64 - pendingBitPos - bitsPerValue);
+    pendingBitPos += bitsPerValue;
+    if (pendingBitPos > blockPref.getBits() - bitsPerValue) {
+      flush();
+    }
+    written++;
+  }
+
+  @Override
+  public void finish() throws IOException {
+    while (written < valueCount) {
+      add(0L);
+    }
+/*    assert written == valueCount :
+            valueCount + " values should be added, but only " + written
+                    + " has been received";*/
+    if (pendingBitPos != 0) { // Flush pending
+      flush();
+    }
+    if (flushedInts % 2 != 0) { // Align to long
+      out.writeInt(0);
+    }
+    out.writeLong(0L); // Dummy last element to be compatible with packed
+  }
+
+  private void flush() throws IOException {
+    // TODO: Align to 64 bit
+    switch (blockPref) {
+      case bit32: {
+        out.writeInt((int)(pending >>> 32));
+//        System.out.println("Flushing @" + blockPref + ": " + Integer.toBinaryString((int)(pending >>> 32)));
+        flushedInts++;
+        break;
+      }
+      case bit64: {
+        out.writeLong(pending);
+//        System.out.println("Flushing @" + blockPref + ": " + Long.toBinaryString((pending)) + " (" + pending + ")");
+        flushedInts += 2;
+        break;
+      }
+      default: throw new UnsupportedOperationException(
+              "The BLOCK " + blockPref + " is unsupported");
+    }
+    pending = 0;
+    pendingBitPos = 0;
+  }
+
+  public String toString() {
+    return "AlignedWriter" + blockPref.getBits()
+            + "(written " + written + "/" + valueCount + " with "
+            + bitsPerValue + " bits/value)";
+  }
+}
Index: src/java/org/apache/lucene/util/packed/GenBitReaders.java
===================================================================
--- src/java/org/apache/lucene/util/packed/GenBitReaders.java	Fri Feb 26 23:40:21 CET 2010
+++ src/java/org/apache/lucene/util/packed/GenBitReaders.java	Fri Feb 26 23:40:21 CET 2010
@@ -0,0 +1,6312 @@
+package org.apache.lucene.util.packed;
+
+import org.apache.lucene.util.RamUsageEstimator;
+import org.apache.lucene.util.packed.PackedInts;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Autogenerated by gen.py DO NOT EDIT!
+// Edited by Toke Eskildsen to make it work with new interfaces.
+// Warning! This is not a real implementation as there are no persistence-
+// suppoert. It is included for performance-measuring
+class GenBitReaders {
+  static abstract class Base extends PackedInts.ReaderImpl {
+    protected final long[] data;
+    protected Base(long[] data, long maxValue) {
+      super(data.length * 64 / PackedInts.bitsRequired(maxValue),
+              PackedInts.bitsRequired(maxValue));
+      this.data = data;
+    }
+    public long ramBytesUsed() {
+      return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER + data.length * RamUsageEstimator.NUM_BYTES_LONG;
+    }
+  }
+
+  final static class Reader1 extends Base {
+    public Reader1(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*1;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 63;
+      case 1:
+        return (data[idx] >>> 62) & 1L;
+      case 2:
+        return (data[idx] >>> 61) & 1L;
+      case 3:
+        return (data[idx] >>> 60) & 1L;
+      case 4:
+        return (data[idx] >>> 59) & 1L;
+      case 5:
+        return (data[idx] >>> 58) & 1L;
+      case 6:
+        return (data[idx] >>> 57) & 1L;
+      case 7:
+        return (data[idx] >>> 56) & 1L;
+      case 8:
+        return (data[idx] >>> 55) & 1L;
+      case 9:
+        return (data[idx] >>> 54) & 1L;
+      case 10:
+        return (data[idx] >>> 53) & 1L;
+      case 11:
+        return (data[idx] >>> 52) & 1L;
+      case 12:
+        return (data[idx] >>> 51) & 1L;
+      case 13:
+        return (data[idx] >>> 50) & 1L;
+      case 14:
+        return (data[idx] >>> 49) & 1L;
+      case 15:
+        return (data[idx] >>> 48) & 1L;
+      case 16:
+        return (data[idx] >>> 47) & 1L;
+      case 17:
+        return (data[idx] >>> 46) & 1L;
+      case 18:
+        return (data[idx] >>> 45) & 1L;
+      case 19:
+        return (data[idx] >>> 44) & 1L;
+      case 20:
+        return (data[idx] >>> 43) & 1L;
+      case 21:
+        return (data[idx] >>> 42) & 1L;
+      case 22:
+        return (data[idx] >>> 41) & 1L;
+      case 23:
+        return (data[idx] >>> 40) & 1L;
+      case 24:
+        return (data[idx] >>> 39) & 1L;
+      case 25:
+        return (data[idx] >>> 38) & 1L;
+      case 26:
+        return (data[idx] >>> 37) & 1L;
+      case 27:
+        return (data[idx] >>> 36) & 1L;
+      case 28:
+        return (data[idx] >>> 35) & 1L;
+      case 29:
+        return (data[idx] >>> 34) & 1L;
+      case 30:
+        return (data[idx] >>> 33) & 1L;
+      case 31:
+        return (data[idx] >>> 32) & 1L;
+      case 32:
+        return (data[idx] >>> 31) & 1L;
+      case 33:
+        return (data[idx] >>> 30) & 1L;
+      case 34:
+        return (data[idx] >>> 29) & 1L;
+      case 35:
+        return (data[idx] >>> 28) & 1L;
+      case 36:
+        return (data[idx] >>> 27) & 1L;
+      case 37:
+        return (data[idx] >>> 26) & 1L;
+      case 38:
+        return (data[idx] >>> 25) & 1L;
+      case 39:
+        return (data[idx] >>> 24) & 1L;
+      case 40:
+        return (data[idx] >>> 23) & 1L;
+      case 41:
+        return (data[idx] >>> 22) & 1L;
+      case 42:
+        return (data[idx] >>> 21) & 1L;
+      case 43:
+        return (data[idx] >>> 20) & 1L;
+      case 44:
+        return (data[idx] >>> 19) & 1L;
+      case 45:
+        return (data[idx] >>> 18) & 1L;
+      case 46:
+        return (data[idx] >>> 17) & 1L;
+      case 47:
+        return (data[idx] >>> 16) & 1L;
+      case 48:
+        return (data[idx] >>> 15) & 1L;
+      case 49:
+        return (data[idx] >>> 14) & 1L;
+      case 50:
+        return (data[idx] >>> 13) & 1L;
+      case 51:
+        return (data[idx] >>> 12) & 1L;
+      case 52:
+        return (data[idx] >>> 11) & 1L;
+      case 53:
+        return (data[idx] >>> 10) & 1L;
+      case 54:
+        return (data[idx] >>> 9) & 1L;
+      case 55:
+        return (data[idx] >>> 8) & 1L;
+      case 56:
+        return (data[idx] >>> 7) & 1L;
+      case 57:
+        return (data[idx] >>> 6) & 1L;
+      case 58:
+        return (data[idx] >>> 5) & 1L;
+      case 59:
+        return (data[idx] >>> 4) & 1L;
+      case 60:
+        return (data[idx] >>> 3) & 1L;
+      case 61:
+        return (data[idx] >>> 2) & 1L;
+      case 62:
+        return (data[idx] >>> 1) & 1L;
+      case 63:
+        return data[idx] & 1L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader2 extends Base {
+    public Reader2(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*2;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 62;
+      case 2:
+        return (data[idx] >>> 60) & 3L;
+      case 4:
+        return (data[idx] >>> 58) & 3L;
+      case 6:
+        return (data[idx] >>> 56) & 3L;
+      case 8:
+        return (data[idx] >>> 54) & 3L;
+      case 10:
+        return (data[idx] >>> 52) & 3L;
+      case 12:
+        return (data[idx] >>> 50) & 3L;
+      case 14:
+        return (data[idx] >>> 48) & 3L;
+      case 16:
+        return (data[idx] >>> 46) & 3L;
+      case 18:
+        return (data[idx] >>> 44) & 3L;
+      case 20:
+        return (data[idx] >>> 42) & 3L;
+      case 22:
+        return (data[idx] >>> 40) & 3L;
+      case 24:
+        return (data[idx] >>> 38) & 3L;
+      case 26:
+        return (data[idx] >>> 36) & 3L;
+      case 28:
+        return (data[idx] >>> 34) & 3L;
+      case 30:
+        return (data[idx] >>> 32) & 3L;
+      case 32:
+        return (data[idx] >>> 30) & 3L;
+      case 34:
+        return (data[idx] >>> 28) & 3L;
+      case 36:
+        return (data[idx] >>> 26) & 3L;
+      case 38:
+        return (data[idx] >>> 24) & 3L;
+      case 40:
+        return (data[idx] >>> 22) & 3L;
+      case 42:
+        return (data[idx] >>> 20) & 3L;
+      case 44:
+        return (data[idx] >>> 18) & 3L;
+      case 46:
+        return (data[idx] >>> 16) & 3L;
+      case 48:
+        return (data[idx] >>> 14) & 3L;
+      case 50:
+        return (data[idx] >>> 12) & 3L;
+      case 52:
+        return (data[idx] >>> 10) & 3L;
+      case 54:
+        return (data[idx] >>> 8) & 3L;
+      case 56:
+        return (data[idx] >>> 6) & 3L;
+      case 58:
+        return (data[idx] >>> 4) & 3L;
+      case 60:
+        return (data[idx] >>> 2) & 3L;
+      case 62:
+        return data[idx] & 3L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader3 extends Base {
+    public Reader3(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*3;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 61;
+      case 3:
+        return (data[idx] >>> 58) & 7L;
+      case 6:
+        return (data[idx] >>> 55) & 7L;
+      case 9:
+        return (data[idx] >>> 52) & 7L;
+      case 12:
+        return (data[idx] >>> 49) & 7L;
+      case 15:
+        return (data[idx] >>> 46) & 7L;
+      case 18:
+        return (data[idx] >>> 43) & 7L;
+      case 21:
+        return (data[idx] >>> 40) & 7L;
+      case 24:
+        return (data[idx] >>> 37) & 7L;
+      case 27:
+        return (data[idx] >>> 34) & 7L;
+      case 30:
+        return (data[idx] >>> 31) & 7L;
+      case 33:
+        return (data[idx] >>> 28) & 7L;
+      case 36:
+        return (data[idx] >>> 25) & 7L;
+      case 39:
+        return (data[idx] >>> 22) & 7L;
+      case 42:
+        return (data[idx] >>> 19) & 7L;
+      case 45:
+        return (data[idx] >>> 16) & 7L;
+      case 48:
+        return (data[idx] >>> 13) & 7L;
+      case 51:
+        return (data[idx] >>> 10) & 7L;
+      case 54:
+        return (data[idx] >>> 7) & 7L;
+      case 57:
+        return (data[idx] >>> 4) & 7L;
+      case 60:
+        return (data[idx] >>> 1) & 7L;
+      case 63:
+        return ((data[idx] & 1L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 59) & 7L;
+      case 5:
+        return (data[idx] >>> 56) & 7L;
+      case 8:
+        return (data[idx] >>> 53) & 7L;
+      case 11:
+        return (data[idx] >>> 50) & 7L;
+      case 14:
+        return (data[idx] >>> 47) & 7L;
+      case 17:
+        return (data[idx] >>> 44) & 7L;
+      case 20:
+        return (data[idx] >>> 41) & 7L;
+      case 23:
+        return (data[idx] >>> 38) & 7L;
+      case 26:
+        return (data[idx] >>> 35) & 7L;
+      case 29:
+        return (data[idx] >>> 32) & 7L;
+      case 32:
+        return (data[idx] >>> 29) & 7L;
+      case 35:
+        return (data[idx] >>> 26) & 7L;
+      case 38:
+        return (data[idx] >>> 23) & 7L;
+      case 41:
+        return (data[idx] >>> 20) & 7L;
+      case 44:
+        return (data[idx] >>> 17) & 7L;
+      case 47:
+        return (data[idx] >>> 14) & 7L;
+      case 50:
+        return (data[idx] >>> 11) & 7L;
+      case 53:
+        return (data[idx] >>> 8) & 7L;
+      case 56:
+        return (data[idx] >>> 5) & 7L;
+      case 59:
+        return (data[idx] >>> 2) & 7L;
+      case 62:
+        return ((data[idx] & 3L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 60) & 7L;
+      case 4:
+        return (data[idx] >>> 57) & 7L;
+      case 7:
+        return (data[idx] >>> 54) & 7L;
+      case 10:
+        return (data[idx] >>> 51) & 7L;
+      case 13:
+        return (data[idx] >>> 48) & 7L;
+      case 16:
+        return (data[idx] >>> 45) & 7L;
+      case 19:
+        return (data[idx] >>> 42) & 7L;
+      case 22:
+        return (data[idx] >>> 39) & 7L;
+      case 25:
+        return (data[idx] >>> 36) & 7L;
+      case 28:
+        return (data[idx] >>> 33) & 7L;
+      case 31:
+        return (data[idx] >>> 30) & 7L;
+      case 34:
+        return (data[idx] >>> 27) & 7L;
+      case 37:
+        return (data[idx] >>> 24) & 7L;
+      case 40:
+        return (data[idx] >>> 21) & 7L;
+      case 43:
+        return (data[idx] >>> 18) & 7L;
+      case 46:
+        return (data[idx] >>> 15) & 7L;
+      case 49:
+        return (data[idx] >>> 12) & 7L;
+      case 52:
+        return (data[idx] >>> 9) & 7L;
+      case 55:
+        return (data[idx] >>> 6) & 7L;
+      case 58:
+        return (data[idx] >>> 3) & 7L;
+      case 61:
+        return data[idx] & 7L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader4 extends Base {
+    public Reader4(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*4;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 60;
+      case 4:
+        return (data[idx] >>> 56) & 15L;
+      case 8:
+        return (data[idx] >>> 52) & 15L;
+      case 12:
+        return (data[idx] >>> 48) & 15L;
+      case 16:
+        return (data[idx] >>> 44) & 15L;
+      case 20:
+        return (data[idx] >>> 40) & 15L;
+      case 24:
+        return (data[idx] >>> 36) & 15L;
+      case 28:
+        return (data[idx] >>> 32) & 15L;
+      case 32:
+        return (data[idx] >>> 28) & 15L;
+      case 36:
+        return (data[idx] >>> 24) & 15L;
+      case 40:
+        return (data[idx] >>> 20) & 15L;
+      case 44:
+        return (data[idx] >>> 16) & 15L;
+      case 48:
+        return (data[idx] >>> 12) & 15L;
+      case 52:
+        return (data[idx] >>> 8) & 15L;
+      case 56:
+        return (data[idx] >>> 4) & 15L;
+      case 60:
+        return data[idx] & 15L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader5 extends Base {
+    public Reader5(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*5;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 59;
+      case 5:
+        return (data[idx] >>> 54) & 31L;
+      case 10:
+        return (data[idx] >>> 49) & 31L;
+      case 15:
+        return (data[idx] >>> 44) & 31L;
+      case 20:
+        return (data[idx] >>> 39) & 31L;
+      case 25:
+        return (data[idx] >>> 34) & 31L;
+      case 30:
+        return (data[idx] >>> 29) & 31L;
+      case 35:
+        return (data[idx] >>> 24) & 31L;
+      case 40:
+        return (data[idx] >>> 19) & 31L;
+      case 45:
+        return (data[idx] >>> 14) & 31L;
+      case 50:
+        return (data[idx] >>> 9) & 31L;
+      case 55:
+        return (data[idx] >>> 4) & 31L;
+      case 60:
+        return ((data[idx] & 15L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 58) & 31L;
+      case 6:
+        return (data[idx] >>> 53) & 31L;
+      case 11:
+        return (data[idx] >>> 48) & 31L;
+      case 16:
+        return (data[idx] >>> 43) & 31L;
+      case 21:
+        return (data[idx] >>> 38) & 31L;
+      case 26:
+        return (data[idx] >>> 33) & 31L;
+      case 31:
+        return (data[idx] >>> 28) & 31L;
+      case 36:
+        return (data[idx] >>> 23) & 31L;
+      case 41:
+        return (data[idx] >>> 18) & 31L;
+      case 46:
+        return (data[idx] >>> 13) & 31L;
+      case 51:
+        return (data[idx] >>> 8) & 31L;
+      case 56:
+        return (data[idx] >>> 3) & 31L;
+      case 61:
+        return ((data[idx] & 7L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 57) & 31L;
+      case 7:
+        return (data[idx] >>> 52) & 31L;
+      case 12:
+        return (data[idx] >>> 47) & 31L;
+      case 17:
+        return (data[idx] >>> 42) & 31L;
+      case 22:
+        return (data[idx] >>> 37) & 31L;
+      case 27:
+        return (data[idx] >>> 32) & 31L;
+      case 32:
+        return (data[idx] >>> 27) & 31L;
+      case 37:
+        return (data[idx] >>> 22) & 31L;
+      case 42:
+        return (data[idx] >>> 17) & 31L;
+      case 47:
+        return (data[idx] >>> 12) & 31L;
+      case 52:
+        return (data[idx] >>> 7) & 31L;
+      case 57:
+        return (data[idx] >>> 2) & 31L;
+      case 62:
+        return ((data[idx] & 3L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 56) & 31L;
+      case 8:
+        return (data[idx] >>> 51) & 31L;
+      case 13:
+        return (data[idx] >>> 46) & 31L;
+      case 18:
+        return (data[idx] >>> 41) & 31L;
+      case 23:
+        return (data[idx] >>> 36) & 31L;
+      case 28:
+        return (data[idx] >>> 31) & 31L;
+      case 33:
+        return (data[idx] >>> 26) & 31L;
+      case 38:
+        return (data[idx] >>> 21) & 31L;
+      case 43:
+        return (data[idx] >>> 16) & 31L;
+      case 48:
+        return (data[idx] >>> 11) & 31L;
+      case 53:
+        return (data[idx] >>> 6) & 31L;
+      case 58:
+        return (data[idx] >>> 1) & 31L;
+      case 63:
+        return ((data[idx] & 1L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 55) & 31L;
+      case 9:
+        return (data[idx] >>> 50) & 31L;
+      case 14:
+        return (data[idx] >>> 45) & 31L;
+      case 19:
+        return (data[idx] >>> 40) & 31L;
+      case 24:
+        return (data[idx] >>> 35) & 31L;
+      case 29:
+        return (data[idx] >>> 30) & 31L;
+      case 34:
+        return (data[idx] >>> 25) & 31L;
+      case 39:
+        return (data[idx] >>> 20) & 31L;
+      case 44:
+        return (data[idx] >>> 15) & 31L;
+      case 49:
+        return (data[idx] >>> 10) & 31L;
+      case 54:
+        return (data[idx] >>> 5) & 31L;
+      case 59:
+        return data[idx] & 31L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader6 extends Base {
+    public Reader6(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*6;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 58;
+      case 6:
+        return (data[idx] >>> 52) & 63L;
+      case 12:
+        return (data[idx] >>> 46) & 63L;
+      case 18:
+        return (data[idx] >>> 40) & 63L;
+      case 24:
+        return (data[idx] >>> 34) & 63L;
+      case 30:
+        return (data[idx] >>> 28) & 63L;
+      case 36:
+        return (data[idx] >>> 22) & 63L;
+      case 42:
+        return (data[idx] >>> 16) & 63L;
+      case 48:
+        return (data[idx] >>> 10) & 63L;
+      case 54:
+        return (data[idx] >>> 4) & 63L;
+      case 60:
+        return ((data[idx] & 15L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 56) & 63L;
+      case 8:
+        return (data[idx] >>> 50) & 63L;
+      case 14:
+        return (data[idx] >>> 44) & 63L;
+      case 20:
+        return (data[idx] >>> 38) & 63L;
+      case 26:
+        return (data[idx] >>> 32) & 63L;
+      case 32:
+        return (data[idx] >>> 26) & 63L;
+      case 38:
+        return (data[idx] >>> 20) & 63L;
+      case 44:
+        return (data[idx] >>> 14) & 63L;
+      case 50:
+        return (data[idx] >>> 8) & 63L;
+      case 56:
+        return (data[idx] >>> 2) & 63L;
+      case 62:
+        return ((data[idx] & 3L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 54) & 63L;
+      case 10:
+        return (data[idx] >>> 48) & 63L;
+      case 16:
+        return (data[idx] >>> 42) & 63L;
+      case 22:
+        return (data[idx] >>> 36) & 63L;
+      case 28:
+        return (data[idx] >>> 30) & 63L;
+      case 34:
+        return (data[idx] >>> 24) & 63L;
+      case 40:
+        return (data[idx] >>> 18) & 63L;
+      case 46:
+        return (data[idx] >>> 12) & 63L;
+      case 52:
+        return (data[idx] >>> 6) & 63L;
+      case 58:
+        return data[idx] & 63L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader7 extends Base {
+    public Reader7(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*7;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 57;
+      case 7:
+        return (data[idx] >>> 50) & 127L;
+      case 14:
+        return (data[idx] >>> 43) & 127L;
+      case 21:
+        return (data[idx] >>> 36) & 127L;
+      case 28:
+        return (data[idx] >>> 29) & 127L;
+      case 35:
+        return (data[idx] >>> 22) & 127L;
+      case 42:
+        return (data[idx] >>> 15) & 127L;
+      case 49:
+        return (data[idx] >>> 8) & 127L;
+      case 56:
+        return (data[idx] >>> 1) & 127L;
+      case 63:
+        return ((data[idx] & 1L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 51) & 127L;
+      case 13:
+        return (data[idx] >>> 44) & 127L;
+      case 20:
+        return (data[idx] >>> 37) & 127L;
+      case 27:
+        return (data[idx] >>> 30) & 127L;
+      case 34:
+        return (data[idx] >>> 23) & 127L;
+      case 41:
+        return (data[idx] >>> 16) & 127L;
+      case 48:
+        return (data[idx] >>> 9) & 127L;
+      case 55:
+        return (data[idx] >>> 2) & 127L;
+      case 62:
+        return ((data[idx] & 3L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 52) & 127L;
+      case 12:
+        return (data[idx] >>> 45) & 127L;
+      case 19:
+        return (data[idx] >>> 38) & 127L;
+      case 26:
+        return (data[idx] >>> 31) & 127L;
+      case 33:
+        return (data[idx] >>> 24) & 127L;
+      case 40:
+        return (data[idx] >>> 17) & 127L;
+      case 47:
+        return (data[idx] >>> 10) & 127L;
+      case 54:
+        return (data[idx] >>> 3) & 127L;
+      case 61:
+        return ((data[idx] & 7L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 53) & 127L;
+      case 11:
+        return (data[idx] >>> 46) & 127L;
+      case 18:
+        return (data[idx] >>> 39) & 127L;
+      case 25:
+        return (data[idx] >>> 32) & 127L;
+      case 32:
+        return (data[idx] >>> 25) & 127L;
+      case 39:
+        return (data[idx] >>> 18) & 127L;
+      case 46:
+        return (data[idx] >>> 11) & 127L;
+      case 53:
+        return (data[idx] >>> 4) & 127L;
+      case 60:
+        return ((data[idx] & 15L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 54) & 127L;
+      case 10:
+        return (data[idx] >>> 47) & 127L;
+      case 17:
+        return (data[idx] >>> 40) & 127L;
+      case 24:
+        return (data[idx] >>> 33) & 127L;
+      case 31:
+        return (data[idx] >>> 26) & 127L;
+      case 38:
+        return (data[idx] >>> 19) & 127L;
+      case 45:
+        return (data[idx] >>> 12) & 127L;
+      case 52:
+        return (data[idx] >>> 5) & 127L;
+      case 59:
+        return ((data[idx] & 31L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 55) & 127L;
+      case 9:
+        return (data[idx] >>> 48) & 127L;
+      case 16:
+        return (data[idx] >>> 41) & 127L;
+      case 23:
+        return (data[idx] >>> 34) & 127L;
+      case 30:
+        return (data[idx] >>> 27) & 127L;
+      case 37:
+        return (data[idx] >>> 20) & 127L;
+      case 44:
+        return (data[idx] >>> 13) & 127L;
+      case 51:
+        return (data[idx] >>> 6) & 127L;
+      case 58:
+        return ((data[idx] & 63L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 56) & 127L;
+      case 8:
+        return (data[idx] >>> 49) & 127L;
+      case 15:
+        return (data[idx] >>> 42) & 127L;
+      case 22:
+        return (data[idx] >>> 35) & 127L;
+      case 29:
+        return (data[idx] >>> 28) & 127L;
+      case 36:
+        return (data[idx] >>> 21) & 127L;
+      case 43:
+        return (data[idx] >>> 14) & 127L;
+      case 50:
+        return (data[idx] >>> 7) & 127L;
+      case 57:
+        return data[idx] & 127L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader9 extends Base {
+    public Reader9(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*9;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 55;
+      case 9:
+        return (data[idx] >>> 46) & 511L;
+      case 18:
+        return (data[idx] >>> 37) & 511L;
+      case 27:
+        return (data[idx] >>> 28) & 511L;
+      case 36:
+        return (data[idx] >>> 19) & 511L;
+      case 45:
+        return (data[idx] >>> 10) & 511L;
+      case 54:
+        return (data[idx] >>> 1) & 511L;
+      case 63:
+        return ((data[idx] & 1L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 47) & 511L;
+      case 17:
+        return (data[idx] >>> 38) & 511L;
+      case 26:
+        return (data[idx] >>> 29) & 511L;
+      case 35:
+        return (data[idx] >>> 20) & 511L;
+      case 44:
+        return (data[idx] >>> 11) & 511L;
+      case 53:
+        return (data[idx] >>> 2) & 511L;
+      case 62:
+        return ((data[idx] & 3L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 48) & 511L;
+      case 16:
+        return (data[idx] >>> 39) & 511L;
+      case 25:
+        return (data[idx] >>> 30) & 511L;
+      case 34:
+        return (data[idx] >>> 21) & 511L;
+      case 43:
+        return (data[idx] >>> 12) & 511L;
+      case 52:
+        return (data[idx] >>> 3) & 511L;
+      case 61:
+        return ((data[idx] & 7L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 49) & 511L;
+      case 15:
+        return (data[idx] >>> 40) & 511L;
+      case 24:
+        return (data[idx] >>> 31) & 511L;
+      case 33:
+        return (data[idx] >>> 22) & 511L;
+      case 42:
+        return (data[idx] >>> 13) & 511L;
+      case 51:
+        return (data[idx] >>> 4) & 511L;
+      case 60:
+        return ((data[idx] & 15L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 50) & 511L;
+      case 14:
+        return (data[idx] >>> 41) & 511L;
+      case 23:
+        return (data[idx] >>> 32) & 511L;
+      case 32:
+        return (data[idx] >>> 23) & 511L;
+      case 41:
+        return (data[idx] >>> 14) & 511L;
+      case 50:
+        return (data[idx] >>> 5) & 511L;
+      case 59:
+        return ((data[idx] & 31L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 51) & 511L;
+      case 13:
+        return (data[idx] >>> 42) & 511L;
+      case 22:
+        return (data[idx] >>> 33) & 511L;
+      case 31:
+        return (data[idx] >>> 24) & 511L;
+      case 40:
+        return (data[idx] >>> 15) & 511L;
+      case 49:
+        return (data[idx] >>> 6) & 511L;
+      case 58:
+        return ((data[idx] & 63L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 52) & 511L;
+      case 12:
+        return (data[idx] >>> 43) & 511L;
+      case 21:
+        return (data[idx] >>> 34) & 511L;
+      case 30:
+        return (data[idx] >>> 25) & 511L;
+      case 39:
+        return (data[idx] >>> 16) & 511L;
+      case 48:
+        return (data[idx] >>> 7) & 511L;
+      case 57:
+        return ((data[idx] & 127L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 53) & 511L;
+      case 11:
+        return (data[idx] >>> 44) & 511L;
+      case 20:
+        return (data[idx] >>> 35) & 511L;
+      case 29:
+        return (data[idx] >>> 26) & 511L;
+      case 38:
+        return (data[idx] >>> 17) & 511L;
+      case 47:
+        return (data[idx] >>> 8) & 511L;
+      case 56:
+        return ((data[idx] & 255L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 54) & 511L;
+      case 10:
+        return (data[idx] >>> 45) & 511L;
+      case 19:
+        return (data[idx] >>> 36) & 511L;
+      case 28:
+        return (data[idx] >>> 27) & 511L;
+      case 37:
+        return (data[idx] >>> 18) & 511L;
+      case 46:
+        return (data[idx] >>> 9) & 511L;
+      case 55:
+        return data[idx] & 511L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader10 extends Base {
+    public Reader10(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*10;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 54;
+      case 10:
+        return (data[idx] >>> 44) & 1023L;
+      case 20:
+        return (data[idx] >>> 34) & 1023L;
+      case 30:
+        return (data[idx] >>> 24) & 1023L;
+      case 40:
+        return (data[idx] >>> 14) & 1023L;
+      case 50:
+        return (data[idx] >>> 4) & 1023L;
+      case 60:
+        return ((data[idx] & 15L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 48) & 1023L;
+      case 16:
+        return (data[idx] >>> 38) & 1023L;
+      case 26:
+        return (data[idx] >>> 28) & 1023L;
+      case 36:
+        return (data[idx] >>> 18) & 1023L;
+      case 46:
+        return (data[idx] >>> 8) & 1023L;
+      case 56:
+        return ((data[idx] & 255L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 52) & 1023L;
+      case 12:
+        return (data[idx] >>> 42) & 1023L;
+      case 22:
+        return (data[idx] >>> 32) & 1023L;
+      case 32:
+        return (data[idx] >>> 22) & 1023L;
+      case 42:
+        return (data[idx] >>> 12) & 1023L;
+      case 52:
+        return (data[idx] >>> 2) & 1023L;
+      case 62:
+        return ((data[idx] & 3L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 46) & 1023L;
+      case 18:
+        return (data[idx] >>> 36) & 1023L;
+      case 28:
+        return (data[idx] >>> 26) & 1023L;
+      case 38:
+        return (data[idx] >>> 16) & 1023L;
+      case 48:
+        return (data[idx] >>> 6) & 1023L;
+      case 58:
+        return ((data[idx] & 63L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 50) & 1023L;
+      case 14:
+        return (data[idx] >>> 40) & 1023L;
+      case 24:
+        return (data[idx] >>> 30) & 1023L;
+      case 34:
+        return (data[idx] >>> 20) & 1023L;
+      case 44:
+        return (data[idx] >>> 10) & 1023L;
+      case 54:
+        return data[idx] & 1023L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader11 extends Base {
+    public Reader11(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*11;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 53;
+      case 11:
+        return (data[idx] >>> 42) & 2047L;
+      case 22:
+        return (data[idx] >>> 31) & 2047L;
+      case 33:
+        return (data[idx] >>> 20) & 2047L;
+      case 44:
+        return (data[idx] >>> 9) & 2047L;
+      case 55:
+        return ((data[idx] & 511L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 51) & 2047L;
+      case 13:
+        return (data[idx] >>> 40) & 2047L;
+      case 24:
+        return (data[idx] >>> 29) & 2047L;
+      case 35:
+        return (data[idx] >>> 18) & 2047L;
+      case 46:
+        return (data[idx] >>> 7) & 2047L;
+      case 57:
+        return ((data[idx] & 127L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 49) & 2047L;
+      case 15:
+        return (data[idx] >>> 38) & 2047L;
+      case 26:
+        return (data[idx] >>> 27) & 2047L;
+      case 37:
+        return (data[idx] >>> 16) & 2047L;
+      case 48:
+        return (data[idx] >>> 5) & 2047L;
+      case 59:
+        return ((data[idx] & 31L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 47) & 2047L;
+      case 17:
+        return (data[idx] >>> 36) & 2047L;
+      case 28:
+        return (data[idx] >>> 25) & 2047L;
+      case 39:
+        return (data[idx] >>> 14) & 2047L;
+      case 50:
+        return (data[idx] >>> 3) & 2047L;
+      case 61:
+        return ((data[idx] & 7L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 45) & 2047L;
+      case 19:
+        return (data[idx] >>> 34) & 2047L;
+      case 30:
+        return (data[idx] >>> 23) & 2047L;
+      case 41:
+        return (data[idx] >>> 12) & 2047L;
+      case 52:
+        return (data[idx] >>> 1) & 2047L;
+      case 63:
+        return ((data[idx] & 1L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 43) & 2047L;
+      case 21:
+        return (data[idx] >>> 32) & 2047L;
+      case 32:
+        return (data[idx] >>> 21) & 2047L;
+      case 43:
+        return (data[idx] >>> 10) & 2047L;
+      case 54:
+        return ((data[idx] & 1023L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 52) & 2047L;
+      case 12:
+        return (data[idx] >>> 41) & 2047L;
+      case 23:
+        return (data[idx] >>> 30) & 2047L;
+      case 34:
+        return (data[idx] >>> 19) & 2047L;
+      case 45:
+        return (data[idx] >>> 8) & 2047L;
+      case 56:
+        return ((data[idx] & 255L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 50) & 2047L;
+      case 14:
+        return (data[idx] >>> 39) & 2047L;
+      case 25:
+        return (data[idx] >>> 28) & 2047L;
+      case 36:
+        return (data[idx] >>> 17) & 2047L;
+      case 47:
+        return (data[idx] >>> 6) & 2047L;
+      case 58:
+        return ((data[idx] & 63L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 48) & 2047L;
+      case 16:
+        return (data[idx] >>> 37) & 2047L;
+      case 27:
+        return (data[idx] >>> 26) & 2047L;
+      case 38:
+        return (data[idx] >>> 15) & 2047L;
+      case 49:
+        return (data[idx] >>> 4) & 2047L;
+      case 60:
+        return ((data[idx] & 15L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 46) & 2047L;
+      case 18:
+        return (data[idx] >>> 35) & 2047L;
+      case 29:
+        return (data[idx] >>> 24) & 2047L;
+      case 40:
+        return (data[idx] >>> 13) & 2047L;
+      case 51:
+        return (data[idx] >>> 2) & 2047L;
+      case 62:
+        return ((data[idx] & 3L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 44) & 2047L;
+      case 20:
+        return (data[idx] >>> 33) & 2047L;
+      case 31:
+        return (data[idx] >>> 22) & 2047L;
+      case 42:
+        return (data[idx] >>> 11) & 2047L;
+      case 53:
+        return data[idx] & 2047L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader12 extends Base {
+    public Reader12(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*12;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 52;
+      case 12:
+        return (data[idx] >>> 40) & 4095L;
+      case 24:
+        return (data[idx] >>> 28) & 4095L;
+      case 36:
+        return (data[idx] >>> 16) & 4095L;
+      case 48:
+        return (data[idx] >>> 4) & 4095L;
+      case 60:
+        return ((data[idx] & 15L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 44) & 4095L;
+      case 20:
+        return (data[idx] >>> 32) & 4095L;
+      case 32:
+        return (data[idx] >>> 20) & 4095L;
+      case 44:
+        return (data[idx] >>> 8) & 4095L;
+      case 56:
+        return ((data[idx] & 255L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 48) & 4095L;
+      case 16:
+        return (data[idx] >>> 36) & 4095L;
+      case 28:
+        return (data[idx] >>> 24) & 4095L;
+      case 40:
+        return (data[idx] >>> 12) & 4095L;
+      case 52:
+        return data[idx] & 4095L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader13 extends Base {
+    public Reader13(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*13;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 51;
+      case 13:
+        return (data[idx] >>> 38) & 8191L;
+      case 26:
+        return (data[idx] >>> 25) & 8191L;
+      case 39:
+        return (data[idx] >>> 12) & 8191L;
+      case 52:
+        return ((data[idx] & 4095L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 50) & 8191L;
+      case 14:
+        return (data[idx] >>> 37) & 8191L;
+      case 27:
+        return (data[idx] >>> 24) & 8191L;
+      case 40:
+        return (data[idx] >>> 11) & 8191L;
+      case 53:
+        return ((data[idx] & 2047L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 49) & 8191L;
+      case 15:
+        return (data[idx] >>> 36) & 8191L;
+      case 28:
+        return (data[idx] >>> 23) & 8191L;
+      case 41:
+        return (data[idx] >>> 10) & 8191L;
+      case 54:
+        return ((data[idx] & 1023L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 48) & 8191L;
+      case 16:
+        return (data[idx] >>> 35) & 8191L;
+      case 29:
+        return (data[idx] >>> 22) & 8191L;
+      case 42:
+        return (data[idx] >>> 9) & 8191L;
+      case 55:
+        return ((data[idx] & 511L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 47) & 8191L;
+      case 17:
+        return (data[idx] >>> 34) & 8191L;
+      case 30:
+        return (data[idx] >>> 21) & 8191L;
+      case 43:
+        return (data[idx] >>> 8) & 8191L;
+      case 56:
+        return ((data[idx] & 255L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 46) & 8191L;
+      case 18:
+        return (data[idx] >>> 33) & 8191L;
+      case 31:
+        return (data[idx] >>> 20) & 8191L;
+      case 44:
+        return (data[idx] >>> 7) & 8191L;
+      case 57:
+        return ((data[idx] & 127L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 45) & 8191L;
+      case 19:
+        return (data[idx] >>> 32) & 8191L;
+      case 32:
+        return (data[idx] >>> 19) & 8191L;
+      case 45:
+        return (data[idx] >>> 6) & 8191L;
+      case 58:
+        return ((data[idx] & 63L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 44) & 8191L;
+      case 20:
+        return (data[idx] >>> 31) & 8191L;
+      case 33:
+        return (data[idx] >>> 18) & 8191L;
+      case 46:
+        return (data[idx] >>> 5) & 8191L;
+      case 59:
+        return ((data[idx] & 31L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 43) & 8191L;
+      case 21:
+        return (data[idx] >>> 30) & 8191L;
+      case 34:
+        return (data[idx] >>> 17) & 8191L;
+      case 47:
+        return (data[idx] >>> 4) & 8191L;
+      case 60:
+        return ((data[idx] & 15L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 42) & 8191L;
+      case 22:
+        return (data[idx] >>> 29) & 8191L;
+      case 35:
+        return (data[idx] >>> 16) & 8191L;
+      case 48:
+        return (data[idx] >>> 3) & 8191L;
+      case 61:
+        return ((data[idx] & 7L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 41) & 8191L;
+      case 23:
+        return (data[idx] >>> 28) & 8191L;
+      case 36:
+        return (data[idx] >>> 15) & 8191L;
+      case 49:
+        return (data[idx] >>> 2) & 8191L;
+      case 62:
+        return ((data[idx] & 3L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 40) & 8191L;
+      case 24:
+        return (data[idx] >>> 27) & 8191L;
+      case 37:
+        return (data[idx] >>> 14) & 8191L;
+      case 50:
+        return (data[idx] >>> 1) & 8191L;
+      case 63:
+        return ((data[idx] & 1L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 39) & 8191L;
+      case 25:
+        return (data[idx] >>> 26) & 8191L;
+      case 38:
+        return (data[idx] >>> 13) & 8191L;
+      case 51:
+        return data[idx] & 8191L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader14 extends Base {
+    public Reader14(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*14;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 50;
+      case 14:
+        return (data[idx] >>> 36) & 16383L;
+      case 28:
+        return (data[idx] >>> 22) & 16383L;
+      case 42:
+        return (data[idx] >>> 8) & 16383L;
+      case 56:
+        return ((data[idx] & 255L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 44) & 16383L;
+      case 20:
+        return (data[idx] >>> 30) & 16383L;
+      case 34:
+        return (data[idx] >>> 16) & 16383L;
+      case 48:
+        return (data[idx] >>> 2) & 16383L;
+      case 62:
+        return ((data[idx] & 3L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 38) & 16383L;
+      case 26:
+        return (data[idx] >>> 24) & 16383L;
+      case 40:
+        return (data[idx] >>> 10) & 16383L;
+      case 54:
+        return ((data[idx] & 1023L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 46) & 16383L;
+      case 18:
+        return (data[idx] >>> 32) & 16383L;
+      case 32:
+        return (data[idx] >>> 18) & 16383L;
+      case 46:
+        return (data[idx] >>> 4) & 16383L;
+      case 60:
+        return ((data[idx] & 15L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 40) & 16383L;
+      case 24:
+        return (data[idx] >>> 26) & 16383L;
+      case 38:
+        return (data[idx] >>> 12) & 16383L;
+      case 52:
+        return ((data[idx] & 4095L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 48) & 16383L;
+      case 16:
+        return (data[idx] >>> 34) & 16383L;
+      case 30:
+        return (data[idx] >>> 20) & 16383L;
+      case 44:
+        return (data[idx] >>> 6) & 16383L;
+      case 58:
+        return ((data[idx] & 63L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 42) & 16383L;
+      case 22:
+        return (data[idx] >>> 28) & 16383L;
+      case 36:
+        return (data[idx] >>> 14) & 16383L;
+      case 50:
+        return data[idx] & 16383L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader15 extends Base {
+    public Reader15(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*15;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 49;
+      case 15:
+        return (data[idx] >>> 34) & 32767L;
+      case 30:
+        return (data[idx] >>> 19) & 32767L;
+      case 45:
+        return (data[idx] >>> 4) & 32767L;
+      case 60:
+        return ((data[idx] & 15L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 38) & 32767L;
+      case 26:
+        return (data[idx] >>> 23) & 32767L;
+      case 41:
+        return (data[idx] >>> 8) & 32767L;
+      case 56:
+        return ((data[idx] & 255L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 42) & 32767L;
+      case 22:
+        return (data[idx] >>> 27) & 32767L;
+      case 37:
+        return (data[idx] >>> 12) & 32767L;
+      case 52:
+        return ((data[idx] & 4095L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 46) & 32767L;
+      case 18:
+        return (data[idx] >>> 31) & 32767L;
+      case 33:
+        return (data[idx] >>> 16) & 32767L;
+      case 48:
+        return (data[idx] >>> 1) & 32767L;
+      case 63:
+        return ((data[idx] & 1L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 35) & 32767L;
+      case 29:
+        return (data[idx] >>> 20) & 32767L;
+      case 44:
+        return (data[idx] >>> 5) & 32767L;
+      case 59:
+        return ((data[idx] & 31L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 39) & 32767L;
+      case 25:
+        return (data[idx] >>> 24) & 32767L;
+      case 40:
+        return (data[idx] >>> 9) & 32767L;
+      case 55:
+        return ((data[idx] & 511L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 43) & 32767L;
+      case 21:
+        return (data[idx] >>> 28) & 32767L;
+      case 36:
+        return (data[idx] >>> 13) & 32767L;
+      case 51:
+        return ((data[idx] & 8191L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 47) & 32767L;
+      case 17:
+        return (data[idx] >>> 32) & 32767L;
+      case 32:
+        return (data[idx] >>> 17) & 32767L;
+      case 47:
+        return (data[idx] >>> 2) & 32767L;
+      case 62:
+        return ((data[idx] & 3L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 36) & 32767L;
+      case 28:
+        return (data[idx] >>> 21) & 32767L;
+      case 43:
+        return (data[idx] >>> 6) & 32767L;
+      case 58:
+        return ((data[idx] & 63L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 40) & 32767L;
+      case 24:
+        return (data[idx] >>> 25) & 32767L;
+      case 39:
+        return (data[idx] >>> 10) & 32767L;
+      case 54:
+        return ((data[idx] & 1023L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 44) & 32767L;
+      case 20:
+        return (data[idx] >>> 29) & 32767L;
+      case 35:
+        return (data[idx] >>> 14) & 32767L;
+      case 50:
+        return ((data[idx] & 16383L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 48) & 32767L;
+      case 16:
+        return (data[idx] >>> 33) & 32767L;
+      case 31:
+        return (data[idx] >>> 18) & 32767L;
+      case 46:
+        return (data[idx] >>> 3) & 32767L;
+      case 61:
+        return ((data[idx] & 7L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 37) & 32767L;
+      case 27:
+        return (data[idx] >>> 22) & 32767L;
+      case 42:
+        return (data[idx] >>> 7) & 32767L;
+      case 57:
+        return ((data[idx] & 127L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 41) & 32767L;
+      case 23:
+        return (data[idx] >>> 26) & 32767L;
+      case 38:
+        return (data[idx] >>> 11) & 32767L;
+      case 53:
+        return ((data[idx] & 2047L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 45) & 32767L;
+      case 19:
+        return (data[idx] >>> 30) & 32767L;
+      case 34:
+        return (data[idx] >>> 15) & 32767L;
+      case 49:
+        return data[idx] & 32767L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader17 extends Base {
+    public Reader17(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*17;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 47;
+      case 17:
+        return (data[idx] >>> 30) & 131071L;
+      case 34:
+        return (data[idx] >>> 13) & 131071L;
+      case 51:
+        return ((data[idx] & 8191L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 43) & 131071L;
+      case 21:
+        return (data[idx] >>> 26) & 131071L;
+      case 38:
+        return (data[idx] >>> 9) & 131071L;
+      case 55:
+        return ((data[idx] & 511L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 39) & 131071L;
+      case 25:
+        return (data[idx] >>> 22) & 131071L;
+      case 42:
+        return (data[idx] >>> 5) & 131071L;
+      case 59:
+        return ((data[idx] & 31L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 35) & 131071L;
+      case 29:
+        return (data[idx] >>> 18) & 131071L;
+      case 46:
+        return (data[idx] >>> 1) & 131071L;
+      case 63:
+        return ((data[idx] & 1L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 31) & 131071L;
+      case 33:
+        return (data[idx] >>> 14) & 131071L;
+      case 50:
+        return ((data[idx] & 16383L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 44) & 131071L;
+      case 20:
+        return (data[idx] >>> 27) & 131071L;
+      case 37:
+        return (data[idx] >>> 10) & 131071L;
+      case 54:
+        return ((data[idx] & 1023L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 40) & 131071L;
+      case 24:
+        return (data[idx] >>> 23) & 131071L;
+      case 41:
+        return (data[idx] >>> 6) & 131071L;
+      case 58:
+        return ((data[idx] & 63L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 36) & 131071L;
+      case 28:
+        return (data[idx] >>> 19) & 131071L;
+      case 45:
+        return (data[idx] >>> 2) & 131071L;
+      case 62:
+        return ((data[idx] & 3L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 32) & 131071L;
+      case 32:
+        return (data[idx] >>> 15) & 131071L;
+      case 49:
+        return ((data[idx] & 32767L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 45) & 131071L;
+      case 19:
+        return (data[idx] >>> 28) & 131071L;
+      case 36:
+        return (data[idx] >>> 11) & 131071L;
+      case 53:
+        return ((data[idx] & 2047L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 41) & 131071L;
+      case 23:
+        return (data[idx] >>> 24) & 131071L;
+      case 40:
+        return (data[idx] >>> 7) & 131071L;
+      case 57:
+        return ((data[idx] & 127L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 37) & 131071L;
+      case 27:
+        return (data[idx] >>> 20) & 131071L;
+      case 44:
+        return (data[idx] >>> 3) & 131071L;
+      case 61:
+        return ((data[idx] & 7L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 33) & 131071L;
+      case 31:
+        return (data[idx] >>> 16) & 131071L;
+      case 48:
+        return ((data[idx] & 65535L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 46) & 131071L;
+      case 18:
+        return (data[idx] >>> 29) & 131071L;
+      case 35:
+        return (data[idx] >>> 12) & 131071L;
+      case 52:
+        return ((data[idx] & 4095L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 42) & 131071L;
+      case 22:
+        return (data[idx] >>> 25) & 131071L;
+      case 39:
+        return (data[idx] >>> 8) & 131071L;
+      case 56:
+        return ((data[idx] & 255L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 38) & 131071L;
+      case 26:
+        return (data[idx] >>> 21) & 131071L;
+      case 43:
+        return (data[idx] >>> 4) & 131071L;
+      case 60:
+        return ((data[idx] & 15L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 34) & 131071L;
+      case 30:
+        return (data[idx] >>> 17) & 131071L;
+      case 47:
+        return data[idx] & 131071L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader18 extends Base {
+    public Reader18(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*18;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 46;
+      case 18:
+        return (data[idx] >>> 28) & 262143L;
+      case 36:
+        return (data[idx] >>> 10) & 262143L;
+      case 54:
+        return ((data[idx] & 1023L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 38) & 262143L;
+      case 26:
+        return (data[idx] >>> 20) & 262143L;
+      case 44:
+        return (data[idx] >>> 2) & 262143L;
+      case 62:
+        return ((data[idx] & 3L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 30) & 262143L;
+      case 34:
+        return (data[idx] >>> 12) & 262143L;
+      case 52:
+        return ((data[idx] & 4095L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 40) & 262143L;
+      case 24:
+        return (data[idx] >>> 22) & 262143L;
+      case 42:
+        return (data[idx] >>> 4) & 262143L;
+      case 60:
+        return ((data[idx] & 15L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 32) & 262143L;
+      case 32:
+        return (data[idx] >>> 14) & 262143L;
+      case 50:
+        return ((data[idx] & 16383L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 42) & 262143L;
+      case 22:
+        return (data[idx] >>> 24) & 262143L;
+      case 40:
+        return (data[idx] >>> 6) & 262143L;
+      case 58:
+        return ((data[idx] & 63L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 34) & 262143L;
+      case 30:
+        return (data[idx] >>> 16) & 262143L;
+      case 48:
+        return ((data[idx] & 65535L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 44) & 262143L;
+      case 20:
+        return (data[idx] >>> 26) & 262143L;
+      case 38:
+        return (data[idx] >>> 8) & 262143L;
+      case 56:
+        return ((data[idx] & 255L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 36) & 262143L;
+      case 28:
+        return (data[idx] >>> 18) & 262143L;
+      case 46:
+        return data[idx] & 262143L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader19 extends Base {
+    public Reader19(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*19;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 45;
+      case 19:
+        return (data[idx] >>> 26) & 524287L;
+      case 38:
+        return (data[idx] >>> 7) & 524287L;
+      case 57:
+        return ((data[idx] & 127L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 33) & 524287L;
+      case 31:
+        return (data[idx] >>> 14) & 524287L;
+      case 50:
+        return ((data[idx] & 16383L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 40) & 524287L;
+      case 24:
+        return (data[idx] >>> 21) & 524287L;
+      case 43:
+        return (data[idx] >>> 2) & 524287L;
+      case 62:
+        return ((data[idx] & 3L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 28) & 524287L;
+      case 36:
+        return (data[idx] >>> 9) & 524287L;
+      case 55:
+        return ((data[idx] & 511L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 35) & 524287L;
+      case 29:
+        return (data[idx] >>> 16) & 524287L;
+      case 48:
+        return ((data[idx] & 65535L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 42) & 524287L;
+      case 22:
+        return (data[idx] >>> 23) & 524287L;
+      case 41:
+        return (data[idx] >>> 4) & 524287L;
+      case 60:
+        return ((data[idx] & 15L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 30) & 524287L;
+      case 34:
+        return (data[idx] >>> 11) & 524287L;
+      case 53:
+        return ((data[idx] & 2047L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 37) & 524287L;
+      case 27:
+        return (data[idx] >>> 18) & 524287L;
+      case 46:
+        return ((data[idx] & 262143L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 44) & 524287L;
+      case 20:
+        return (data[idx] >>> 25) & 524287L;
+      case 39:
+        return (data[idx] >>> 6) & 524287L;
+      case 58:
+        return ((data[idx] & 63L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 32) & 524287L;
+      case 32:
+        return (data[idx] >>> 13) & 524287L;
+      case 51:
+        return ((data[idx] & 8191L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 39) & 524287L;
+      case 25:
+        return (data[idx] >>> 20) & 524287L;
+      case 44:
+        return (data[idx] >>> 1) & 524287L;
+      case 63:
+        return ((data[idx] & 1L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 27) & 524287L;
+      case 37:
+        return (data[idx] >>> 8) & 524287L;
+      case 56:
+        return ((data[idx] & 255L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 34) & 524287L;
+      case 30:
+        return (data[idx] >>> 15) & 524287L;
+      case 49:
+        return ((data[idx] & 32767L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 41) & 524287L;
+      case 23:
+        return (data[idx] >>> 22) & 524287L;
+      case 42:
+        return (data[idx] >>> 3) & 524287L;
+      case 61:
+        return ((data[idx] & 7L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 29) & 524287L;
+      case 35:
+        return (data[idx] >>> 10) & 524287L;
+      case 54:
+        return ((data[idx] & 1023L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 36) & 524287L;
+      case 28:
+        return (data[idx] >>> 17) & 524287L;
+      case 47:
+        return ((data[idx] & 131071L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 43) & 524287L;
+      case 21:
+        return (data[idx] >>> 24) & 524287L;
+      case 40:
+        return (data[idx] >>> 5) & 524287L;
+      case 59:
+        return ((data[idx] & 31L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 31) & 524287L;
+      case 33:
+        return (data[idx] >>> 12) & 524287L;
+      case 52:
+        return ((data[idx] & 4095L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 38) & 524287L;
+      case 26:
+        return (data[idx] >>> 19) & 524287L;
+      case 45:
+        return data[idx] & 524287L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader20 extends Base {
+    public Reader20(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*20;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 44;
+      case 20:
+        return (data[idx] >>> 24) & 1048575L;
+      case 40:
+        return (data[idx] >>> 4) & 1048575L;
+      case 60:
+        return ((data[idx] & 15L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 28) & 1048575L;
+      case 36:
+        return (data[idx] >>> 8) & 1048575L;
+      case 56:
+        return ((data[idx] & 255L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 32) & 1048575L;
+      case 32:
+        return (data[idx] >>> 12) & 1048575L;
+      case 52:
+        return ((data[idx] & 4095L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 36) & 1048575L;
+      case 28:
+        return (data[idx] >>> 16) & 1048575L;
+      case 48:
+        return ((data[idx] & 65535L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 40) & 1048575L;
+      case 24:
+        return (data[idx] >>> 20) & 1048575L;
+      case 44:
+        return data[idx] & 1048575L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader21 extends Base {
+    public Reader21(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*21;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 43;
+      case 21:
+        return (data[idx] >>> 22) & 2097151L;
+      case 42:
+        return (data[idx] >>> 1) & 2097151L;
+      case 63:
+        return ((data[idx] & 1L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 23) & 2097151L;
+      case 41:
+        return (data[idx] >>> 2) & 2097151L;
+      case 62:
+        return ((data[idx] & 3L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 24) & 2097151L;
+      case 40:
+        return (data[idx] >>> 3) & 2097151L;
+      case 61:
+        return ((data[idx] & 7L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 25) & 2097151L;
+      case 39:
+        return (data[idx] >>> 4) & 2097151L;
+      case 60:
+        return ((data[idx] & 15L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 26) & 2097151L;
+      case 38:
+        return (data[idx] >>> 5) & 2097151L;
+      case 59:
+        return ((data[idx] & 31L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 27) & 2097151L;
+      case 37:
+        return (data[idx] >>> 6) & 2097151L;
+      case 58:
+        return ((data[idx] & 63L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 28) & 2097151L;
+      case 36:
+        return (data[idx] >>> 7) & 2097151L;
+      case 57:
+        return ((data[idx] & 127L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 29) & 2097151L;
+      case 35:
+        return (data[idx] >>> 8) & 2097151L;
+      case 56:
+        return ((data[idx] & 255L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 30) & 2097151L;
+      case 34:
+        return (data[idx] >>> 9) & 2097151L;
+      case 55:
+        return ((data[idx] & 511L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 31) & 2097151L;
+      case 33:
+        return (data[idx] >>> 10) & 2097151L;
+      case 54:
+        return ((data[idx] & 1023L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 32) & 2097151L;
+      case 32:
+        return (data[idx] >>> 11) & 2097151L;
+      case 53:
+        return ((data[idx] & 2047L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 33) & 2097151L;
+      case 31:
+        return (data[idx] >>> 12) & 2097151L;
+      case 52:
+        return ((data[idx] & 4095L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 34) & 2097151L;
+      case 30:
+        return (data[idx] >>> 13) & 2097151L;
+      case 51:
+        return ((data[idx] & 8191L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 35) & 2097151L;
+      case 29:
+        return (data[idx] >>> 14) & 2097151L;
+      case 50:
+        return ((data[idx] & 16383L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 36) & 2097151L;
+      case 28:
+        return (data[idx] >>> 15) & 2097151L;
+      case 49:
+        return ((data[idx] & 32767L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 37) & 2097151L;
+      case 27:
+        return (data[idx] >>> 16) & 2097151L;
+      case 48:
+        return ((data[idx] & 65535L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 38) & 2097151L;
+      case 26:
+        return (data[idx] >>> 17) & 2097151L;
+      case 47:
+        return ((data[idx] & 131071L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 39) & 2097151L;
+      case 25:
+        return (data[idx] >>> 18) & 2097151L;
+      case 46:
+        return ((data[idx] & 262143L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 40) & 2097151L;
+      case 24:
+        return (data[idx] >>> 19) & 2097151L;
+      case 45:
+        return ((data[idx] & 524287L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 41) & 2097151L;
+      case 23:
+        return (data[idx] >>> 20) & 2097151L;
+      case 44:
+        return ((data[idx] & 1048575L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 42) & 2097151L;
+      case 22:
+        return (data[idx] >>> 21) & 2097151L;
+      case 43:
+        return data[idx] & 2097151L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader22 extends Base {
+    public Reader22(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*22;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 42;
+      case 22:
+        return (data[idx] >>> 20) & 4194303L;
+      case 44:
+        return ((data[idx] & 1048575L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 40) & 4194303L;
+      case 24:
+        return (data[idx] >>> 18) & 4194303L;
+      case 46:
+        return ((data[idx] & 262143L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 38) & 4194303L;
+      case 26:
+        return (data[idx] >>> 16) & 4194303L;
+      case 48:
+        return ((data[idx] & 65535L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 36) & 4194303L;
+      case 28:
+        return (data[idx] >>> 14) & 4194303L;
+      case 50:
+        return ((data[idx] & 16383L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 34) & 4194303L;
+      case 30:
+        return (data[idx] >>> 12) & 4194303L;
+      case 52:
+        return ((data[idx] & 4095L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 32) & 4194303L;
+      case 32:
+        return (data[idx] >>> 10) & 4194303L;
+      case 54:
+        return ((data[idx] & 1023L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 30) & 4194303L;
+      case 34:
+        return (data[idx] >>> 8) & 4194303L;
+      case 56:
+        return ((data[idx] & 255L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 28) & 4194303L;
+      case 36:
+        return (data[idx] >>> 6) & 4194303L;
+      case 58:
+        return ((data[idx] & 63L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 26) & 4194303L;
+      case 38:
+        return (data[idx] >>> 4) & 4194303L;
+      case 60:
+        return ((data[idx] & 15L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 24) & 4194303L;
+      case 40:
+        return (data[idx] >>> 2) & 4194303L;
+      case 62:
+        return ((data[idx] & 3L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 22) & 4194303L;
+      case 42:
+        return data[idx] & 4194303L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader23 extends Base {
+    public Reader23(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*23;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 41;
+      case 23:
+        return (data[idx] >>> 18) & 8388607L;
+      case 46:
+        return ((data[idx] & 262143L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 36) & 8388607L;
+      case 28:
+        return (data[idx] >>> 13) & 8388607L;
+      case 51:
+        return ((data[idx] & 8191L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 31) & 8388607L;
+      case 33:
+        return (data[idx] >>> 8) & 8388607L;
+      case 56:
+        return ((data[idx] & 255L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 26) & 8388607L;
+      case 38:
+        return (data[idx] >>> 3) & 8388607L;
+      case 61:
+        return ((data[idx] & 7L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 21) & 8388607L;
+      case 43:
+        return ((data[idx] & 2097151L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 39) & 8388607L;
+      case 25:
+        return (data[idx] >>> 16) & 8388607L;
+      case 48:
+        return ((data[idx] & 65535L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 34) & 8388607L;
+      case 30:
+        return (data[idx] >>> 11) & 8388607L;
+      case 53:
+        return ((data[idx] & 2047L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 29) & 8388607L;
+      case 35:
+        return (data[idx] >>> 6) & 8388607L;
+      case 58:
+        return ((data[idx] & 63L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 24) & 8388607L;
+      case 40:
+        return (data[idx] >>> 1) & 8388607L;
+      case 63:
+        return ((data[idx] & 1L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 19) & 8388607L;
+      case 45:
+        return ((data[idx] & 524287L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 37) & 8388607L;
+      case 27:
+        return (data[idx] >>> 14) & 8388607L;
+      case 50:
+        return ((data[idx] & 16383L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 32) & 8388607L;
+      case 32:
+        return (data[idx] >>> 9) & 8388607L;
+      case 55:
+        return ((data[idx] & 511L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 27) & 8388607L;
+      case 37:
+        return (data[idx] >>> 4) & 8388607L;
+      case 60:
+        return ((data[idx] & 15L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 22) & 8388607L;
+      case 42:
+        return ((data[idx] & 4194303L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 40) & 8388607L;
+      case 24:
+        return (data[idx] >>> 17) & 8388607L;
+      case 47:
+        return ((data[idx] & 131071L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 35) & 8388607L;
+      case 29:
+        return (data[idx] >>> 12) & 8388607L;
+      case 52:
+        return ((data[idx] & 4095L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 30) & 8388607L;
+      case 34:
+        return (data[idx] >>> 7) & 8388607L;
+      case 57:
+        return ((data[idx] & 127L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 25) & 8388607L;
+      case 39:
+        return (data[idx] >>> 2) & 8388607L;
+      case 62:
+        return ((data[idx] & 3L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return (data[idx] >>> 20) & 8388607L;
+      case 44:
+        return ((data[idx] & 1048575L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 38) & 8388607L;
+      case 26:
+        return (data[idx] >>> 15) & 8388607L;
+      case 49:
+        return ((data[idx] & 32767L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 33) & 8388607L;
+      case 31:
+        return (data[idx] >>> 10) & 8388607L;
+      case 54:
+        return ((data[idx] & 1023L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 28) & 8388607L;
+      case 36:
+        return (data[idx] >>> 5) & 8388607L;
+      case 59:
+        return ((data[idx] & 31L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 23) & 8388607L;
+      case 41:
+        return data[idx] & 8388607L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader24 extends Base {
+    public Reader24(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*24;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 40;
+      case 24:
+        return (data[idx] >>> 16) & 16777215L;
+      case 48:
+        return ((data[idx] & 65535L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 32) & 16777215L;
+      case 32:
+        return (data[idx] >>> 8) & 16777215L;
+      case 56:
+        return ((data[idx] & 255L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 24) & 16777215L;
+      case 40:
+        return data[idx] & 16777215L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader25 extends Base {
+    public Reader25(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*25;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 39;
+      case 25:
+        return (data[idx] >>> 14) & 33554431L;
+      case 50:
+        return ((data[idx] & 16383L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 28) & 33554431L;
+      case 36:
+        return (data[idx] >>> 3) & 33554431L;
+      case 61:
+        return ((data[idx] & 7L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 17) & 33554431L;
+      case 47:
+        return ((data[idx] & 131071L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 31) & 33554431L;
+      case 33:
+        return (data[idx] >>> 6) & 33554431L;
+      case 58:
+        return ((data[idx] & 63L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 20) & 33554431L;
+      case 44:
+        return ((data[idx] & 1048575L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 34) & 33554431L;
+      case 30:
+        return (data[idx] >>> 9) & 33554431L;
+      case 55:
+        return ((data[idx] & 511L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 23) & 33554431L;
+      case 41:
+        return ((data[idx] & 8388607L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 37) & 33554431L;
+      case 27:
+        return (data[idx] >>> 12) & 33554431L;
+      case 52:
+        return ((data[idx] & 4095L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 26) & 33554431L;
+      case 38:
+        return (data[idx] >>> 1) & 33554431L;
+      case 63:
+        return ((data[idx] & 1L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 15) & 33554431L;
+      case 49:
+        return ((data[idx] & 32767L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 29) & 33554431L;
+      case 35:
+        return (data[idx] >>> 4) & 33554431L;
+      case 60:
+        return ((data[idx] & 15L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return (data[idx] >>> 18) & 33554431L;
+      case 46:
+        return ((data[idx] & 262143L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 32) & 33554431L;
+      case 32:
+        return (data[idx] >>> 7) & 33554431L;
+      case 57:
+        return ((data[idx] & 127L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 21) & 33554431L;
+      case 43:
+        return ((data[idx] & 2097151L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 35) & 33554431L;
+      case 29:
+        return (data[idx] >>> 10) & 33554431L;
+      case 54:
+        return ((data[idx] & 1023L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 24) & 33554431L;
+      case 40:
+        return ((data[idx] & 16777215L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 38) & 33554431L;
+      case 26:
+        return (data[idx] >>> 13) & 33554431L;
+      case 51:
+        return ((data[idx] & 8191L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 27) & 33554431L;
+      case 37:
+        return (data[idx] >>> 2) & 33554431L;
+      case 62:
+        return ((data[idx] & 3L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return (data[idx] >>> 16) & 33554431L;
+      case 48:
+        return ((data[idx] & 65535L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 30) & 33554431L;
+      case 34:
+        return (data[idx] >>> 5) & 33554431L;
+      case 59:
+        return ((data[idx] & 31L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 19) & 33554431L;
+      case 45:
+        return ((data[idx] & 524287L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 33) & 33554431L;
+      case 31:
+        return (data[idx] >>> 8) & 33554431L;
+      case 56:
+        return ((data[idx] & 255L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 22) & 33554431L;
+      case 42:
+        return ((data[idx] & 4194303L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 36) & 33554431L;
+      case 28:
+        return (data[idx] >>> 11) & 33554431L;
+      case 53:
+        return ((data[idx] & 2047L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 25) & 33554431L;
+      case 39:
+        return data[idx] & 33554431L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader26 extends Base {
+    public Reader26(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*26;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 38;
+      case 26:
+        return (data[idx] >>> 12) & 67108863L;
+      case 52:
+        return ((data[idx] & 4095L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 24) & 67108863L;
+      case 40:
+        return ((data[idx] & 16777215L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 36) & 67108863L;
+      case 28:
+        return (data[idx] >>> 10) & 67108863L;
+      case 54:
+        return ((data[idx] & 1023L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 22) & 67108863L;
+      case 42:
+        return ((data[idx] & 4194303L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 34) & 67108863L;
+      case 30:
+        return (data[idx] >>> 8) & 67108863L;
+      case 56:
+        return ((data[idx] & 255L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 20) & 67108863L;
+      case 44:
+        return ((data[idx] & 1048575L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 32) & 67108863L;
+      case 32:
+        return (data[idx] >>> 6) & 67108863L;
+      case 58:
+        return ((data[idx] & 63L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 18) & 67108863L;
+      case 46:
+        return ((data[idx] & 262143L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 30) & 67108863L;
+      case 34:
+        return (data[idx] >>> 4) & 67108863L;
+      case 60:
+        return ((data[idx] & 15L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 16) & 67108863L;
+      case 48:
+        return ((data[idx] & 65535L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 28) & 67108863L;
+      case 36:
+        return (data[idx] >>> 2) & 67108863L;
+      case 62:
+        return ((data[idx] & 3L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 14) & 67108863L;
+      case 50:
+        return ((data[idx] & 16383L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 26) & 67108863L;
+      case 38:
+        return data[idx] & 67108863L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader27 extends Base {
+    public Reader27(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*27;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 37;
+      case 27:
+        return (data[idx] >>> 10) & 134217727L;
+      case 54:
+        return ((data[idx] & 1023L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 20) & 134217727L;
+      case 44:
+        return ((data[idx] & 1048575L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 30) & 134217727L;
+      case 34:
+        return (data[idx] >>> 3) & 134217727L;
+      case 61:
+        return ((data[idx] & 7L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 13) & 134217727L;
+      case 51:
+        return ((data[idx] & 8191L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 23) & 134217727L;
+      case 41:
+        return ((data[idx] & 8388607L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 33) & 134217727L;
+      case 31:
+        return (data[idx] >>> 6) & 134217727L;
+      case 58:
+        return ((data[idx] & 63L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return (data[idx] >>> 16) & 134217727L;
+      case 48:
+        return ((data[idx] & 65535L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 26) & 134217727L;
+      case 38:
+        return ((data[idx] & 67108863L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 36) & 134217727L;
+      case 28:
+        return (data[idx] >>> 9) & 134217727L;
+      case 55:
+        return ((data[idx] & 511L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 19) & 134217727L;
+      case 45:
+        return ((data[idx] & 524287L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 29) & 134217727L;
+      case 35:
+        return (data[idx] >>> 2) & 134217727L;
+      case 62:
+        return ((data[idx] & 3L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return (data[idx] >>> 12) & 134217727L;
+      case 52:
+        return ((data[idx] & 4095L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 22) & 134217727L;
+      case 42:
+        return ((data[idx] & 4194303L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 32) & 134217727L;
+      case 32:
+        return (data[idx] >>> 5) & 134217727L;
+      case 59:
+        return ((data[idx] & 31L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 15) & 134217727L;
+      case 49:
+        return ((data[idx] & 32767L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 25) & 134217727L;
+      case 39:
+        return ((data[idx] & 33554431L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 35) & 134217727L;
+      case 29:
+        return (data[idx] >>> 8) & 134217727L;
+      case 56:
+        return ((data[idx] & 255L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 18) & 134217727L;
+      case 46:
+        return ((data[idx] & 262143L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 28) & 134217727L;
+      case 36:
+        return (data[idx] >>> 1) & 134217727L;
+      case 63:
+        return ((data[idx] & 1L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return (data[idx] >>> 11) & 134217727L;
+      case 53:
+        return ((data[idx] & 2047L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 21) & 134217727L;
+      case 43:
+        return ((data[idx] & 2097151L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 31) & 134217727L;
+      case 33:
+        return (data[idx] >>> 4) & 134217727L;
+      case 60:
+        return ((data[idx] & 15L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return (data[idx] >>> 14) & 134217727L;
+      case 50:
+        return ((data[idx] & 16383L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 24) & 134217727L;
+      case 40:
+        return ((data[idx] & 16777215L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 34) & 134217727L;
+      case 30:
+        return (data[idx] >>> 7) & 134217727L;
+      case 57:
+        return ((data[idx] & 127L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 17) & 134217727L;
+      case 47:
+        return ((data[idx] & 131071L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 27) & 134217727L;
+      case 37:
+        return data[idx] & 134217727L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader28 extends Base {
+    public Reader28(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*28;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 36;
+      case 28:
+        return (data[idx] >>> 8) & 268435455L;
+      case 56:
+        return ((data[idx] & 255L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 16) & 268435455L;
+      case 48:
+        return ((data[idx] & 65535L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 24) & 268435455L;
+      case 40:
+        return ((data[idx] & 16777215L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 32) & 268435455L;
+      case 32:
+        return (data[idx] >>> 4) & 268435455L;
+      case 60:
+        return ((data[idx] & 15L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 12) & 268435455L;
+      case 52:
+        return ((data[idx] & 4095L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 20) & 268435455L;
+      case 44:
+        return ((data[idx] & 1048575L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 28) & 268435455L;
+      case 36:
+        return data[idx] & 268435455L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader29 extends Base {
+    public Reader29(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*29;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 35;
+      case 29:
+        return (data[idx] >>> 6) & 536870911L;
+      case 58:
+        return ((data[idx] & 63L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return (data[idx] >>> 12) & 536870911L;
+      case 52:
+        return ((data[idx] & 4095L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 18) & 536870911L;
+      case 46:
+        return ((data[idx] & 262143L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 24) & 536870911L;
+      case 40:
+        return ((data[idx] & 16777215L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 30) & 536870911L;
+      case 34:
+        return (data[idx] >>> 1) & 536870911L;
+      case 63:
+        return ((data[idx] & 1L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return (data[idx] >>> 7) & 536870911L;
+      case 57:
+        return ((data[idx] & 127L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 13) & 536870911L;
+      case 51:
+        return ((data[idx] & 8191L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 19) & 536870911L;
+      case 45:
+        return ((data[idx] & 524287L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 25) & 536870911L;
+      case 39:
+        return ((data[idx] & 33554431L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 31) & 536870911L;
+      case 33:
+        return (data[idx] >>> 2) & 536870911L;
+      case 62:
+        return ((data[idx] & 3L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return (data[idx] >>> 8) & 536870911L;
+      case 56:
+        return ((data[idx] & 255L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return (data[idx] >>> 14) & 536870911L;
+      case 50:
+        return ((data[idx] & 16383L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 20) & 536870911L;
+      case 44:
+        return ((data[idx] & 1048575L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 26) & 536870911L;
+      case 38:
+        return ((data[idx] & 67108863L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 32) & 536870911L;
+      case 32:
+        return (data[idx] >>> 3) & 536870911L;
+      case 61:
+        return ((data[idx] & 7L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return (data[idx] >>> 9) & 536870911L;
+      case 55:
+        return ((data[idx] & 511L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 15) & 536870911L;
+      case 49:
+        return ((data[idx] & 32767L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 21) & 536870911L;
+      case 43:
+        return ((data[idx] & 2097151L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 27) & 536870911L;
+      case 37:
+        return ((data[idx] & 134217727L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 33) & 536870911L;
+      case 31:
+        return (data[idx] >>> 4) & 536870911L;
+      case 60:
+        return ((data[idx] & 15L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return (data[idx] >>> 10) & 536870911L;
+      case 54:
+        return ((data[idx] & 1023L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 16) & 536870911L;
+      case 48:
+        return ((data[idx] & 65535L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 22) & 536870911L;
+      case 42:
+        return ((data[idx] & 4194303L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 28) & 536870911L;
+      case 36:
+        return ((data[idx] & 268435455L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 34) & 536870911L;
+      case 30:
+        return (data[idx] >>> 5) & 536870911L;
+      case 59:
+        return ((data[idx] & 31L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 11) & 536870911L;
+      case 53:
+        return ((data[idx] & 2047L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 17) & 536870911L;
+      case 47:
+        return ((data[idx] & 131071L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 23) & 536870911L;
+      case 41:
+        return ((data[idx] & 8388607L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 29) & 536870911L;
+      case 35:
+        return data[idx] & 536870911L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader30 extends Base {
+    public Reader30(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*30;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 34;
+      case 30:
+        return (data[idx] >>> 4) & 1073741823L;
+      case 60:
+        return ((data[idx] & 15L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return (data[idx] >>> 8) & 1073741823L;
+      case 56:
+        return ((data[idx] & 255L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 12) & 1073741823L;
+      case 52:
+        return ((data[idx] & 4095L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 16) & 1073741823L;
+      case 48:
+        return ((data[idx] & 65535L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 20) & 1073741823L;
+      case 44:
+        return ((data[idx] & 1048575L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 24) & 1073741823L;
+      case 40:
+        return ((data[idx] & 16777215L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 28) & 1073741823L;
+      case 36:
+        return ((data[idx] & 268435455L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 32) & 1073741823L;
+      case 32:
+        return (data[idx] >>> 2) & 1073741823L;
+      case 62:
+        return ((data[idx] & 3L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return (data[idx] >>> 6) & 1073741823L;
+      case 58:
+        return ((data[idx] & 63L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 10) & 1073741823L;
+      case 54:
+        return ((data[idx] & 1023L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 14) & 1073741823L;
+      case 50:
+        return ((data[idx] & 16383L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 18) & 1073741823L;
+      case 46:
+        return ((data[idx] & 262143L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 22) & 1073741823L;
+      case 42:
+        return ((data[idx] & 4194303L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 26) & 1073741823L;
+      case 38:
+        return ((data[idx] & 67108863L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 30) & 1073741823L;
+      case 34:
+        return data[idx] & 1073741823L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader31 extends Base {
+    public Reader31(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*31;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 33;
+      case 31:
+        return (data[idx] >>> 2) & 2147483647L;
+      case 62:
+        return ((data[idx] & 3L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return (data[idx] >>> 4) & 2147483647L;
+      case 60:
+        return ((data[idx] & 15L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return (data[idx] >>> 6) & 2147483647L;
+      case 58:
+        return ((data[idx] & 63L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return (data[idx] >>> 8) & 2147483647L;
+      case 56:
+        return ((data[idx] & 255L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return (data[idx] >>> 10) & 2147483647L;
+      case 54:
+        return ((data[idx] & 1023L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return (data[idx] >>> 12) & 2147483647L;
+      case 52:
+        return ((data[idx] & 4095L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 14) & 2147483647L;
+      case 50:
+        return ((data[idx] & 16383L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 16) & 2147483647L;
+      case 48:
+        return ((data[idx] & 65535L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 18) & 2147483647L;
+      case 46:
+        return ((data[idx] & 262143L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 20) & 2147483647L;
+      case 44:
+        return ((data[idx] & 1048575L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 22) & 2147483647L;
+      case 42:
+        return ((data[idx] & 4194303L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 24) & 2147483647L;
+      case 40:
+        return ((data[idx] & 16777215L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 26) & 2147483647L;
+      case 38:
+        return ((data[idx] & 67108863L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 28) & 2147483647L;
+      case 36:
+        return ((data[idx] & 268435455L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 30) & 2147483647L;
+      case 34:
+        return ((data[idx] & 1073741823L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 32) & 2147483647L;
+      case 32:
+        return (data[idx] >>> 1) & 2147483647L;
+      case 63:
+        return ((data[idx] & 1L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return (data[idx] >>> 3) & 2147483647L;
+      case 61:
+        return ((data[idx] & 7L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return (data[idx] >>> 5) & 2147483647L;
+      case 59:
+        return ((data[idx] & 31L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return (data[idx] >>> 7) & 2147483647L;
+      case 57:
+        return ((data[idx] & 127L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 9) & 2147483647L;
+      case 55:
+        return ((data[idx] & 511L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 11) & 2147483647L;
+      case 53:
+        return ((data[idx] & 2047L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 13) & 2147483647L;
+      case 51:
+        return ((data[idx] & 8191L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 15) & 2147483647L;
+      case 49:
+        return ((data[idx] & 32767L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 17) & 2147483647L;
+      case 47:
+        return ((data[idx] & 131071L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 19) & 2147483647L;
+      case 45:
+        return ((data[idx] & 524287L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 21) & 2147483647L;
+      case 43:
+        return ((data[idx] & 2097151L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 23) & 2147483647L;
+      case 41:
+        return ((data[idx] & 8388607L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 25) & 2147483647L;
+      case 39:
+        return ((data[idx] & 33554431L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 27) & 2147483647L;
+      case 37:
+        return ((data[idx] & 134217727L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 29) & 2147483647L;
+      case 35:
+        return ((data[idx] & 536870911L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 31) & 2147483647L;
+      case 33:
+        return data[idx] & 2147483647L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader33 extends Base {
+    public Reader33(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*33;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 31;
+      case 33:
+        return ((data[idx] & 2147483647L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 29) & 8589934591L;
+      case 35:
+        return ((data[idx] & 536870911L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 27) & 8589934591L;
+      case 37:
+        return ((data[idx] & 134217727L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 25) & 8589934591L;
+      case 39:
+        return ((data[idx] & 33554431L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 23) & 8589934591L;
+      case 41:
+        return ((data[idx] & 8388607L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 21) & 8589934591L;
+      case 43:
+        return ((data[idx] & 2097151L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 19) & 8589934591L;
+      case 45:
+        return ((data[idx] & 524287L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 17) & 8589934591L;
+      case 47:
+        return ((data[idx] & 131071L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 15) & 8589934591L;
+      case 49:
+        return ((data[idx] & 32767L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 13) & 8589934591L;
+      case 51:
+        return ((data[idx] & 8191L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 11) & 8589934591L;
+      case 53:
+        return ((data[idx] & 2047L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 9) & 8589934591L;
+      case 55:
+        return ((data[idx] & 511L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 7) & 8589934591L;
+      case 57:
+        return ((data[idx] & 127L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return (data[idx] >>> 5) & 8589934591L;
+      case 59:
+        return ((data[idx] & 31L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return (data[idx] >>> 3) & 8589934591L;
+      case 61:
+        return ((data[idx] & 7L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return (data[idx] >>> 1) & 8589934591L;
+      case 63:
+        return ((data[idx] & 1L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 30) & 8589934591L;
+      case 34:
+        return ((data[idx] & 1073741823L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 28) & 8589934591L;
+      case 36:
+        return ((data[idx] & 268435455L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 26) & 8589934591L;
+      case 38:
+        return ((data[idx] & 67108863L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 24) & 8589934591L;
+      case 40:
+        return ((data[idx] & 16777215L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 22) & 8589934591L;
+      case 42:
+        return ((data[idx] & 4194303L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 20) & 8589934591L;
+      case 44:
+        return ((data[idx] & 1048575L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 18) & 8589934591L;
+      case 46:
+        return ((data[idx] & 262143L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 16) & 8589934591L;
+      case 48:
+        return ((data[idx] & 65535L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 14) & 8589934591L;
+      case 50:
+        return ((data[idx] & 16383L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 12) & 8589934591L;
+      case 52:
+        return ((data[idx] & 4095L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return (data[idx] >>> 10) & 8589934591L;
+      case 54:
+        return ((data[idx] & 1023L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return (data[idx] >>> 8) & 8589934591L;
+      case 56:
+        return ((data[idx] & 255L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return (data[idx] >>> 6) & 8589934591L;
+      case 58:
+        return ((data[idx] & 63L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return (data[idx] >>> 4) & 8589934591L;
+      case 60:
+        return ((data[idx] & 15L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return (data[idx] >>> 2) & 8589934591L;
+      case 62:
+        return ((data[idx] & 3L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return data[idx] & 8589934591L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader34 extends Base {
+    public Reader34(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*34;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 30;
+      case 34:
+        return ((data[idx] & 1073741823L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 26) & 17179869183L;
+      case 38:
+        return ((data[idx] & 67108863L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 22) & 17179869183L;
+      case 42:
+        return ((data[idx] & 4194303L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 18) & 17179869183L;
+      case 46:
+        return ((data[idx] & 262143L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 14) & 17179869183L;
+      case 50:
+        return ((data[idx] & 16383L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 10) & 17179869183L;
+      case 54:
+        return ((data[idx] & 1023L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 6) & 17179869183L;
+      case 58:
+        return ((data[idx] & 63L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return (data[idx] >>> 2) & 17179869183L;
+      case 62:
+        return ((data[idx] & 3L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 28) & 17179869183L;
+      case 36:
+        return ((data[idx] & 268435455L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 24) & 17179869183L;
+      case 40:
+        return ((data[idx] & 16777215L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 20) & 17179869183L;
+      case 44:
+        return ((data[idx] & 1048575L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 16) & 17179869183L;
+      case 48:
+        return ((data[idx] & 65535L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 12) & 17179869183L;
+      case 52:
+        return ((data[idx] & 4095L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 8) & 17179869183L;
+      case 56:
+        return ((data[idx] & 255L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return (data[idx] >>> 4) & 17179869183L;
+      case 60:
+        return ((data[idx] & 15L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return data[idx] & 17179869183L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader35 extends Base {
+    public Reader35(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*35;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 29;
+      case 35:
+        return ((data[idx] & 536870911L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 23) & 34359738367L;
+      case 41:
+        return ((data[idx] & 8388607L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 17) & 34359738367L;
+      case 47:
+        return ((data[idx] & 131071L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 11) & 34359738367L;
+      case 53:
+        return ((data[idx] & 2047L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 5) & 34359738367L;
+      case 59:
+        return ((data[idx] & 31L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 28) & 34359738367L;
+      case 36:
+        return ((data[idx] & 268435455L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 22) & 34359738367L;
+      case 42:
+        return ((data[idx] & 4194303L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 16) & 34359738367L;
+      case 48:
+        return ((data[idx] & 65535L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 10) & 34359738367L;
+      case 54:
+        return ((data[idx] & 1023L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return (data[idx] >>> 4) & 34359738367L;
+      case 60:
+        return ((data[idx] & 15L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 27) & 34359738367L;
+      case 37:
+        return ((data[idx] & 134217727L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 21) & 34359738367L;
+      case 43:
+        return ((data[idx] & 2097151L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 15) & 34359738367L;
+      case 49:
+        return ((data[idx] & 32767L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 9) & 34359738367L;
+      case 55:
+        return ((data[idx] & 511L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return (data[idx] >>> 3) & 34359738367L;
+      case 61:
+        return ((data[idx] & 7L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 26) & 34359738367L;
+      case 38:
+        return ((data[idx] & 67108863L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 20) & 34359738367L;
+      case 44:
+        return ((data[idx] & 1048575L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 14) & 34359738367L;
+      case 50:
+        return ((data[idx] & 16383L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return (data[idx] >>> 8) & 34359738367L;
+      case 56:
+        return ((data[idx] & 255L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return (data[idx] >>> 2) & 34359738367L;
+      case 62:
+        return ((data[idx] & 3L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 25) & 34359738367L;
+      case 39:
+        return ((data[idx] & 33554431L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 19) & 34359738367L;
+      case 45:
+        return ((data[idx] & 524287L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 13) & 34359738367L;
+      case 51:
+        return ((data[idx] & 8191L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 7) & 34359738367L;
+      case 57:
+        return ((data[idx] & 127L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return (data[idx] >>> 1) & 34359738367L;
+      case 63:
+        return ((data[idx] & 1L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 24) & 34359738367L;
+      case 40:
+        return ((data[idx] & 16777215L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 18) & 34359738367L;
+      case 46:
+        return ((data[idx] & 262143L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 12) & 34359738367L;
+      case 52:
+        return ((data[idx] & 4095L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return (data[idx] >>> 6) & 34359738367L;
+      case 58:
+        return ((data[idx] & 63L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return data[idx] & 34359738367L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader36 extends Base {
+    public Reader36(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*36;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 28;
+      case 36:
+        return ((data[idx] & 268435455L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 20) & 68719476735L;
+      case 44:
+        return ((data[idx] & 1048575L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 12) & 68719476735L;
+      case 52:
+        return ((data[idx] & 4095L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 4) & 68719476735L;
+      case 60:
+        return ((data[idx] & 15L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 24) & 68719476735L;
+      case 40:
+        return ((data[idx] & 16777215L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 16) & 68719476735L;
+      case 48:
+        return ((data[idx] & 65535L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 8) & 68719476735L;
+      case 56:
+        return ((data[idx] & 255L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return data[idx] & 68719476735L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader37 extends Base {
+    public Reader37(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*37;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 27;
+      case 37:
+        return ((data[idx] & 134217727L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 17) & 137438953471L;
+      case 47:
+        return ((data[idx] & 131071L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 7) & 137438953471L;
+      case 57:
+        return ((data[idx] & 127L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 24) & 137438953471L;
+      case 40:
+        return ((data[idx] & 16777215L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 14) & 137438953471L;
+      case 50:
+        return ((data[idx] & 16383L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return (data[idx] >>> 4) & 137438953471L;
+      case 60:
+        return ((data[idx] & 15L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 21) & 137438953471L;
+      case 43:
+        return ((data[idx] & 2097151L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 11) & 137438953471L;
+      case 53:
+        return ((data[idx] & 2047L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return (data[idx] >>> 1) & 137438953471L;
+      case 63:
+        return ((data[idx] & 1L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 18) & 137438953471L;
+      case 46:
+        return ((data[idx] & 262143L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 8) & 137438953471L;
+      case 56:
+        return ((data[idx] & 255L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 25) & 137438953471L;
+      case 39:
+        return ((data[idx] & 33554431L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 15) & 137438953471L;
+      case 49:
+        return ((data[idx] & 32767L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 5) & 137438953471L;
+      case 59:
+        return ((data[idx] & 31L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 22) & 137438953471L;
+      case 42:
+        return ((data[idx] & 4194303L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 12) & 137438953471L;
+      case 52:
+        return ((data[idx] & 4095L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return (data[idx] >>> 2) & 137438953471L;
+      case 62:
+        return ((data[idx] & 3L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 19) & 137438953471L;
+      case 45:
+        return ((data[idx] & 524287L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 9) & 137438953471L;
+      case 55:
+        return ((data[idx] & 511L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 26) & 137438953471L;
+      case 38:
+        return ((data[idx] & 67108863L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 16) & 137438953471L;
+      case 48:
+        return ((data[idx] & 65535L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return (data[idx] >>> 6) & 137438953471L;
+      case 58:
+        return ((data[idx] & 63L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 23) & 137438953471L;
+      case 41:
+        return ((data[idx] & 8388607L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 13) & 137438953471L;
+      case 51:
+        return ((data[idx] & 8191L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 3) & 137438953471L;
+      case 61:
+        return ((data[idx] & 7L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 20) & 137438953471L;
+      case 44:
+        return ((data[idx] & 1048575L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 10) & 137438953471L;
+      case 54:
+        return ((data[idx] & 1023L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return data[idx] & 137438953471L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader38 extends Base {
+    public Reader38(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*38;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 26;
+      case 38:
+        return ((data[idx] & 67108863L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 14) & 274877906943L;
+      case 50:
+        return ((data[idx] & 16383L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 2) & 274877906943L;
+      case 62:
+        return ((data[idx] & 3L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 16) & 274877906943L;
+      case 48:
+        return ((data[idx] & 65535L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 4) & 274877906943L;
+      case 60:
+        return ((data[idx] & 15L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 18) & 274877906943L;
+      case 46:
+        return ((data[idx] & 262143L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 6) & 274877906943L;
+      case 58:
+        return ((data[idx] & 63L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 20) & 274877906943L;
+      case 44:
+        return ((data[idx] & 1048575L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 8) & 274877906943L;
+      case 56:
+        return ((data[idx] & 255L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 22) & 274877906943L;
+      case 42:
+        return ((data[idx] & 4194303L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 10) & 274877906943L;
+      case 54:
+        return ((data[idx] & 1023L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 24) & 274877906943L;
+      case 40:
+        return ((data[idx] & 16777215L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 12) & 274877906943L;
+      case 52:
+        return ((data[idx] & 4095L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return data[idx] & 274877906943L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader39 extends Base {
+    public Reader39(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*39;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 25;
+      case 39:
+        return ((data[idx] & 33554431L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 11) & 549755813887L;
+      case 53:
+        return ((data[idx] & 2047L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 22) & 549755813887L;
+      case 42:
+        return ((data[idx] & 4194303L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 8) & 549755813887L;
+      case 56:
+        return ((data[idx] & 255L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 19) & 549755813887L;
+      case 45:
+        return ((data[idx] & 524287L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 5) & 549755813887L;
+      case 59:
+        return ((data[idx] & 31L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 16) & 549755813887L;
+      case 48:
+        return ((data[idx] & 65535L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return (data[idx] >>> 2) & 549755813887L;
+      case 62:
+        return ((data[idx] & 3L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 13) & 549755813887L;
+      case 51:
+        return ((data[idx] & 8191L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 24) & 549755813887L;
+      case 40:
+        return ((data[idx] & 16777215L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 10) & 549755813887L;
+      case 54:
+        return ((data[idx] & 1023L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 21) & 549755813887L;
+      case 43:
+        return ((data[idx] & 2097151L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 7) & 549755813887L;
+      case 57:
+        return ((data[idx] & 127L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 18) & 549755813887L;
+      case 46:
+        return ((data[idx] & 262143L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return (data[idx] >>> 4) & 549755813887L;
+      case 60:
+        return ((data[idx] & 15L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 15) & 549755813887L;
+      case 49:
+        return ((data[idx] & 32767L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return (data[idx] >>> 1) & 549755813887L;
+      case 63:
+        return ((data[idx] & 1L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 12) & 549755813887L;
+      case 52:
+        return ((data[idx] & 4095L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 23) & 549755813887L;
+      case 41:
+        return ((data[idx] & 8388607L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 9) & 549755813887L;
+      case 55:
+        return ((data[idx] & 511L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 20) & 549755813887L;
+      case 44:
+        return ((data[idx] & 1048575L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 6) & 549755813887L;
+      case 58:
+        return ((data[idx] & 63L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 17) & 549755813887L;
+      case 47:
+        return ((data[idx] & 131071L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 3) & 549755813887L;
+      case 61:
+        return ((data[idx] & 7L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 14) & 549755813887L;
+      case 50:
+        return ((data[idx] & 16383L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return data[idx] & 549755813887L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader40 extends Base {
+    public Reader40(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*40;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 24;
+      case 40:
+        return ((data[idx] & 16777215L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 8) & 1099511627775L;
+      case 56:
+        return ((data[idx] & 255L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 16) & 1099511627775L;
+      case 48:
+        return ((data[idx] & 65535L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return data[idx] & 1099511627775L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader41 extends Base {
+    public Reader41(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*41;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 23;
+      case 41:
+        return ((data[idx] & 8388607L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 5) & 2199023255551L;
+      case 59:
+        return ((data[idx] & 31L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 10) & 2199023255551L;
+      case 54:
+        return ((data[idx] & 1023L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 15) & 2199023255551L;
+      case 49:
+        return ((data[idx] & 32767L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 20) & 2199023255551L;
+      case 44:
+        return ((data[idx] & 1048575L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return (data[idx] >>> 2) & 2199023255551L;
+      case 62:
+        return ((data[idx] & 3L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 7) & 2199023255551L;
+      case 57:
+        return ((data[idx] & 127L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 12) & 2199023255551L;
+      case 52:
+        return ((data[idx] & 4095L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 17) & 2199023255551L;
+      case 47:
+        return ((data[idx] & 131071L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 22) & 2199023255551L;
+      case 42:
+        return ((data[idx] & 4194303L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 4) & 2199023255551L;
+      case 60:
+        return ((data[idx] & 15L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 9) & 2199023255551L;
+      case 55:
+        return ((data[idx] & 511L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 14) & 2199023255551L;
+      case 50:
+        return ((data[idx] & 16383L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 19) & 2199023255551L;
+      case 45:
+        return ((data[idx] & 524287L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return (data[idx] >>> 1) & 2199023255551L;
+      case 63:
+        return ((data[idx] & 1L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 6) & 2199023255551L;
+      case 58:
+        return ((data[idx] & 63L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 11) & 2199023255551L;
+      case 53:
+        return ((data[idx] & 2047L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 16) & 2199023255551L;
+      case 48:
+        return ((data[idx] & 65535L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 21) & 2199023255551L;
+      case 43:
+        return ((data[idx] & 2097151L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 3) & 2199023255551L;
+      case 61:
+        return ((data[idx] & 7L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 8) & 2199023255551L;
+      case 56:
+        return ((data[idx] & 255L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 13) & 2199023255551L;
+      case 51:
+        return ((data[idx] & 8191L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 18) & 2199023255551L;
+      case 46:
+        return ((data[idx] & 262143L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return data[idx] & 2199023255551L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader42 extends Base {
+    public Reader42(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*42;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 22;
+      case 42:
+        return ((data[idx] & 4194303L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 2) & 4398046511103L;
+      case 62:
+        return ((data[idx] & 3L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 4) & 4398046511103L;
+      case 60:
+        return ((data[idx] & 15L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 6) & 4398046511103L;
+      case 58:
+        return ((data[idx] & 63L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 8) & 4398046511103L;
+      case 56:
+        return ((data[idx] & 255L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 10) & 4398046511103L;
+      case 54:
+        return ((data[idx] & 1023L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 12) & 4398046511103L;
+      case 52:
+        return ((data[idx] & 4095L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 14) & 4398046511103L;
+      case 50:
+        return ((data[idx] & 16383L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 16) & 4398046511103L;
+      case 48:
+        return ((data[idx] & 65535L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 18) & 4398046511103L;
+      case 46:
+        return ((data[idx] & 262143L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 20) & 4398046511103L;
+      case 44:
+        return ((data[idx] & 1048575L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return data[idx] & 4398046511103L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader43 extends Base {
+    public Reader43(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*43;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 21;
+      case 43:
+        return ((data[idx] & 2097151L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 20) & 8796093022207L;
+      case 44:
+        return ((data[idx] & 1048575L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 19) & 8796093022207L;
+      case 45:
+        return ((data[idx] & 524287L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 18) & 8796093022207L;
+      case 46:
+        return ((data[idx] & 262143L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 17) & 8796093022207L;
+      case 47:
+        return ((data[idx] & 131071L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 16) & 8796093022207L;
+      case 48:
+        return ((data[idx] & 65535L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 15) & 8796093022207L;
+      case 49:
+        return ((data[idx] & 32767L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 14) & 8796093022207L;
+      case 50:
+        return ((data[idx] & 16383L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 13) & 8796093022207L;
+      case 51:
+        return ((data[idx] & 8191L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 12) & 8796093022207L;
+      case 52:
+        return ((data[idx] & 4095L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 11) & 8796093022207L;
+      case 53:
+        return ((data[idx] & 2047L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 10) & 8796093022207L;
+      case 54:
+        return ((data[idx] & 1023L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 9) & 8796093022207L;
+      case 55:
+        return ((data[idx] & 511L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 8) & 8796093022207L;
+      case 56:
+        return ((data[idx] & 255L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 7) & 8796093022207L;
+      case 57:
+        return ((data[idx] & 127L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 6) & 8796093022207L;
+      case 58:
+        return ((data[idx] & 63L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 5) & 8796093022207L;
+      case 59:
+        return ((data[idx] & 31L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 4) & 8796093022207L;
+      case 60:
+        return ((data[idx] & 15L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 3) & 8796093022207L;
+      case 61:
+        return ((data[idx] & 7L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return (data[idx] >>> 2) & 8796093022207L;
+      case 62:
+        return ((data[idx] & 3L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return (data[idx] >>> 1) & 8796093022207L;
+      case 63:
+        return ((data[idx] & 1L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return data[idx] & 8796093022207L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader44 extends Base {
+    public Reader44(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*44;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 20;
+      case 44:
+        return ((data[idx] & 1048575L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 16) & 17592186044415L;
+      case 48:
+        return ((data[idx] & 65535L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 12) & 17592186044415L;
+      case 52:
+        return ((data[idx] & 4095L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 8) & 17592186044415L;
+      case 56:
+        return ((data[idx] & 255L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 4) & 17592186044415L;
+      case 60:
+        return ((data[idx] & 15L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return data[idx] & 17592186044415L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader45 extends Base {
+    public Reader45(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*45;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 19;
+      case 45:
+        return ((data[idx] & 524287L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 12) & 35184372088831L;
+      case 52:
+        return ((data[idx] & 4095L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 5) & 35184372088831L;
+      case 59:
+        return ((data[idx] & 31L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return ((data[idx] & 8796093022207L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 17) & 35184372088831L;
+      case 47:
+        return ((data[idx] & 131071L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 10) & 35184372088831L;
+      case 54:
+        return ((data[idx] & 1023L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 3) & 35184372088831L;
+      case 61:
+        return ((data[idx] & 7L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 15) & 35184372088831L;
+      case 49:
+        return ((data[idx] & 32767L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 8) & 35184372088831L;
+      case 56:
+        return ((data[idx] & 255L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return (data[idx] >>> 1) & 35184372088831L;
+      case 63:
+        return ((data[idx] & 1L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 13) & 35184372088831L;
+      case 51:
+        return ((data[idx] & 8191L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 6) & 35184372088831L;
+      case 58:
+        return ((data[idx] & 63L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 18) & 35184372088831L;
+      case 46:
+        return ((data[idx] & 262143L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 11) & 35184372088831L;
+      case 53:
+        return ((data[idx] & 2047L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 4) & 35184372088831L;
+      case 60:
+        return ((data[idx] & 15L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 16) & 35184372088831L;
+      case 48:
+        return ((data[idx] & 65535L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 9) & 35184372088831L;
+      case 55:
+        return ((data[idx] & 511L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return (data[idx] >>> 2) & 35184372088831L;
+      case 62:
+        return ((data[idx] & 3L) << 43) | (data[1+idx] >>> 21);
+      case 43:
+        return ((data[idx] & 2097151L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 14) & 35184372088831L;
+      case 50:
+        return ((data[idx] & 16383L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 7) & 35184372088831L;
+      case 57:
+        return ((data[idx] & 127L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return data[idx] & 35184372088831L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader46 extends Base {
+    public Reader46(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*46;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 18;
+      case 46:
+        return ((data[idx] & 262143L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 8) & 70368744177663L;
+      case 56:
+        return ((data[idx] & 255L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 16) & 70368744177663L;
+      case 48:
+        return ((data[idx] & 65535L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 6) & 70368744177663L;
+      case 58:
+        return ((data[idx] & 63L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 14) & 70368744177663L;
+      case 50:
+        return ((data[idx] & 16383L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 4) & 70368744177663L;
+      case 60:
+        return ((data[idx] & 15L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 12) & 70368744177663L;
+      case 52:
+        return ((data[idx] & 4095L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 2) & 70368744177663L;
+      case 62:
+        return ((data[idx] & 3L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 10) & 70368744177663L;
+      case 54:
+        return ((data[idx] & 1023L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return data[idx] & 70368744177663L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader47 extends Base {
+    public Reader47(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*47;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 17;
+      case 47:
+        return ((data[idx] & 131071L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 4) & 140737488355327L;
+      case 60:
+        return ((data[idx] & 15L) << 43) | (data[1+idx] >>> 21);
+      case 43:
+        return ((data[idx] & 2097151L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 8) & 140737488355327L;
+      case 56:
+        return ((data[idx] & 255L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 12) & 140737488355327L;
+      case 52:
+        return ((data[idx] & 4095L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 16) & 140737488355327L;
+      case 48:
+        return ((data[idx] & 65535L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 3) & 140737488355327L;
+      case 61:
+        return ((data[idx] & 7L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 7) & 140737488355327L;
+      case 57:
+        return ((data[idx] & 127L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 11) & 140737488355327L;
+      case 53:
+        return ((data[idx] & 2047L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return ((data[idx] & 35184372088831L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 15) & 140737488355327L;
+      case 49:
+        return ((data[idx] & 32767L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return (data[idx] >>> 2) & 140737488355327L;
+      case 62:
+        return ((data[idx] & 3L) << 45) | (data[1+idx] >>> 19);
+      case 45:
+        return ((data[idx] & 524287L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 6) & 140737488355327L;
+      case 58:
+        return ((data[idx] & 63L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 10) & 140737488355327L;
+      case 54:
+        return ((data[idx] & 1023L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 14) & 140737488355327L;
+      case 50:
+        return ((data[idx] & 16383L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return (data[idx] >>> 1) & 140737488355327L;
+      case 63:
+        return ((data[idx] & 1L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 5) & 140737488355327L;
+      case 59:
+        return ((data[idx] & 31L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 9) & 140737488355327L;
+      case 55:
+        return ((data[idx] & 511L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return ((data[idx] & 8796093022207L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 13) & 140737488355327L;
+      case 51:
+        return ((data[idx] & 8191L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return data[idx] & 140737488355327L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader48 extends Base {
+    public Reader48(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*48;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 16;
+      case 48:
+        return ((data[idx] & 65535L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return data[idx] & 281474976710655L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader49 extends Base {
+    public Reader49(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*49;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 15;
+      case 49:
+        return ((data[idx] & 32767L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return ((data[idx] & 35184372088831L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 11) & 562949953421311L;
+      case 53:
+        return ((data[idx] & 2047L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 7) & 562949953421311L;
+      case 57:
+        return ((data[idx] & 127L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 3) & 562949953421311L;
+      case 61:
+        return ((data[idx] & 7L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 14) & 562949953421311L;
+      case 50:
+        return ((data[idx] & 16383L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 10) & 562949953421311L;
+      case 54:
+        return ((data[idx] & 1023L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 6) & 562949953421311L;
+      case 58:
+        return ((data[idx] & 63L) << 43) | (data[1+idx] >>> 21);
+      case 43:
+        return ((data[idx] & 2097151L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return (data[idx] >>> 2) & 562949953421311L;
+      case 62:
+        return ((data[idx] & 3L) << 47) | (data[1+idx] >>> 17);
+      case 47:
+        return ((data[idx] & 131071L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return ((data[idx] & 140737488355327L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 13) & 562949953421311L;
+      case 51:
+        return ((data[idx] & 8191L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return ((data[idx] & 8796093022207L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 9) & 562949953421311L;
+      case 55:
+        return ((data[idx] & 511L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 5) & 562949953421311L;
+      case 59:
+        return ((data[idx] & 31L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return (data[idx] >>> 1) & 562949953421311L;
+      case 63:
+        return ((data[idx] & 1L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 12) & 562949953421311L;
+      case 52:
+        return ((data[idx] & 4095L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 8) & 562949953421311L;
+      case 56:
+        return ((data[idx] & 255L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 4) & 562949953421311L;
+      case 60:
+        return ((data[idx] & 15L) << 45) | (data[1+idx] >>> 19);
+      case 45:
+        return ((data[idx] & 524287L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return data[idx] & 562949953421311L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader50 extends Base {
+    public Reader50(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*50;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 14;
+      case 50:
+        return ((data[idx] & 16383L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 6) & 1125899906842623L;
+      case 58:
+        return ((data[idx] & 63L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 12) & 1125899906842623L;
+      case 52:
+        return ((data[idx] & 4095L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 4) & 1125899906842623L;
+      case 60:
+        return ((data[idx] & 15L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 10) & 1125899906842623L;
+      case 54:
+        return ((data[idx] & 1023L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 2) & 1125899906842623L;
+      case 62:
+        return ((data[idx] & 3L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 8) & 1125899906842623L;
+      case 56:
+        return ((data[idx] & 255L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return data[idx] & 1125899906842623L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader51 extends Base {
+    public Reader51(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*51;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 13;
+      case 51:
+        return ((data[idx] & 8191L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return (data[idx] >>> 1) & 2251799813685247L;
+      case 63:
+        return ((data[idx] & 1L) << 50) | (data[1+idx] >>> 14);
+      case 50:
+        return ((data[idx] & 16383L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return (data[idx] >>> 2) & 2251799813685247L;
+      case 62:
+        return ((data[idx] & 3L) << 49) | (data[1+idx] >>> 15);
+      case 49:
+        return ((data[idx] & 32767L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 3) & 2251799813685247L;
+      case 61:
+        return ((data[idx] & 7L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 4) & 2251799813685247L;
+      case 60:
+        return ((data[idx] & 15L) << 47) | (data[1+idx] >>> 17);
+      case 47:
+        return ((data[idx] & 131071L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return ((data[idx] & 8796093022207L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 5) & 2251799813685247L;
+      case 59:
+        return ((data[idx] & 31L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 6) & 2251799813685247L;
+      case 58:
+        return ((data[idx] & 63L) << 45) | (data[1+idx] >>> 19);
+      case 45:
+        return ((data[idx] & 524287L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return ((data[idx] & 35184372088831L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 7) & 2251799813685247L;
+      case 57:
+        return ((data[idx] & 127L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 8) & 2251799813685247L;
+      case 56:
+        return ((data[idx] & 255L) << 43) | (data[1+idx] >>> 21);
+      case 43:
+        return ((data[idx] & 2097151L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return ((data[idx] & 140737488355327L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 9) & 2251799813685247L;
+      case 55:
+        return ((data[idx] & 511L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 10) & 2251799813685247L;
+      case 54:
+        return ((data[idx] & 1023L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return ((data[idx] & 562949953421311L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 11) & 2251799813685247L;
+      case 53:
+        return ((data[idx] & 2047L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return ((data[idx] & 1125899906842623L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 12) & 2251799813685247L;
+      case 52:
+        return ((data[idx] & 4095L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return data[idx] & 2251799813685247L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader52 extends Base {
+    public Reader52(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*52;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 12;
+      case 52:
+        return ((data[idx] & 4095L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 8) & 4503599627370495L;
+      case 56:
+        return ((data[idx] & 255L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 4) & 4503599627370495L;
+      case 60:
+        return ((data[idx] & 15L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return data[idx] & 4503599627370495L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader53 extends Base {
+    public Reader53(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*53;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 11;
+      case 53:
+        return ((data[idx] & 2047L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return (data[idx] >>> 2) & 9007199254740991L;
+      case 62:
+        return ((data[idx] & 3L) << 51) | (data[1+idx] >>> 13);
+      case 51:
+        return ((data[idx] & 8191L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 4) & 9007199254740991L;
+      case 60:
+        return ((data[idx] & 15L) << 49) | (data[1+idx] >>> 15);
+      case 49:
+        return ((data[idx] & 32767L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 6) & 9007199254740991L;
+      case 58:
+        return ((data[idx] & 63L) << 47) | (data[1+idx] >>> 17);
+      case 47:
+        return ((data[idx] & 131071L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return ((data[idx] & 1125899906842623L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 8) & 9007199254740991L;
+      case 56:
+        return ((data[idx] & 255L) << 45) | (data[1+idx] >>> 19);
+      case 45:
+        return ((data[idx] & 524287L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return ((data[idx] & 4503599627370495L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 10) & 9007199254740991L;
+      case 54:
+        return ((data[idx] & 1023L) << 43) | (data[1+idx] >>> 21);
+      case 43:
+        return ((data[idx] & 2097151L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return ((data[idx] & 8796093022207L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return (data[idx] >>> 1) & 9007199254740991L;
+      case 63:
+        return ((data[idx] & 1L) << 52) | (data[1+idx] >>> 12);
+      case 52:
+        return ((data[idx] & 4095L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return ((data[idx] & 35184372088831L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 3) & 9007199254740991L;
+      case 61:
+        return ((data[idx] & 7L) << 50) | (data[1+idx] >>> 14);
+      case 50:
+        return ((data[idx] & 16383L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return ((data[idx] & 140737488355327L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 5) & 9007199254740991L;
+      case 59:
+        return ((data[idx] & 31L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return ((data[idx] & 562949953421311L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 7) & 9007199254740991L;
+      case 57:
+        return ((data[idx] & 127L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return ((data[idx] & 2251799813685247L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 9) & 9007199254740991L;
+      case 55:
+        return ((data[idx] & 511L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return data[idx] & 9007199254740991L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader54 extends Base {
+    public Reader54(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*54;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 10;
+      case 54:
+        return ((data[idx] & 1023L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return ((data[idx] & 1125899906842623L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 6) & 18014398509481983L;
+      case 58:
+        return ((data[idx] & 63L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 2) & 18014398509481983L;
+      case 62:
+        return ((data[idx] & 3L) << 52) | (data[1+idx] >>> 12);
+      case 52:
+        return ((data[idx] & 4095L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return ((data[idx] & 4503599627370495L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 8) & 18014398509481983L;
+      case 56:
+        return ((data[idx] & 255L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 4) & 18014398509481983L;
+      case 60:
+        return ((data[idx] & 15L) << 50) | (data[1+idx] >>> 14);
+      case 50:
+        return ((data[idx] & 16383L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return data[idx] & 18014398509481983L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader55 extends Base {
+    public Reader55(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*55;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 9;
+      case 55:
+        return ((data[idx] & 511L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return ((data[idx] & 35184372088831L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return ((data[idx] & 18014398509481983L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 8) & 36028797018963967L;
+      case 56:
+        return ((data[idx] & 255L) << 47) | (data[1+idx] >>> 17);
+      case 47:
+        return ((data[idx] & 131071L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return ((data[idx] & 9007199254740991L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 7) & 36028797018963967L;
+      case 57:
+        return ((data[idx] & 127L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return ((data[idx] & 8796093022207L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return ((data[idx] & 4503599627370495L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 6) & 36028797018963967L;
+      case 58:
+        return ((data[idx] & 63L) << 49) | (data[1+idx] >>> 15);
+      case 49:
+        return ((data[idx] & 32767L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return ((data[idx] & 2251799813685247L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 5) & 36028797018963967L;
+      case 59:
+        return ((data[idx] & 31L) << 50) | (data[1+idx] >>> 14);
+      case 50:
+        return ((data[idx] & 16383L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return ((data[idx] & 1125899906842623L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 4) & 36028797018963967L;
+      case 60:
+        return ((data[idx] & 15L) << 51) | (data[1+idx] >>> 13);
+      case 51:
+        return ((data[idx] & 8191L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return ((data[idx] & 562949953421311L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 3) & 36028797018963967L;
+      case 61:
+        return ((data[idx] & 7L) << 52) | (data[1+idx] >>> 12);
+      case 52:
+        return ((data[idx] & 4095L) << 43) | (data[1+idx] >>> 21);
+      case 43:
+        return ((data[idx] & 2097151L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return (data[idx] >>> 2) & 36028797018963967L;
+      case 62:
+        return ((data[idx] & 3L) << 53) | (data[1+idx] >>> 11);
+      case 53:
+        return ((data[idx] & 2047L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return ((data[idx] & 140737488355327L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return (data[idx] >>> 1) & 36028797018963967L;
+      case 63:
+        return ((data[idx] & 1L) << 54) | (data[1+idx] >>> 10);
+      case 54:
+        return ((data[idx] & 1023L) << 45) | (data[1+idx] >>> 19);
+      case 45:
+        return ((data[idx] & 524287L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return data[idx] & 36028797018963967L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader56 extends Base {
+    public Reader56(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*56;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 8;
+      case 56:
+        return ((data[idx] & 255L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return data[idx] & 72057594037927935L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader57 extends Base {
+    public Reader57(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*57;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 7;
+      case 57:
+        return ((data[idx] & 127L) << 50) | (data[1+idx] >>> 14);
+      case 50:
+        return ((data[idx] & 16383L) << 43) | (data[1+idx] >>> 21);
+      case 43:
+        return ((data[idx] & 2097151L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return ((data[idx] & 562949953421311L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return ((data[idx] & 72057594037927935L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 6) & 144115188075855871L;
+      case 58:
+        return ((data[idx] & 63L) << 51) | (data[1+idx] >>> 13);
+      case 51:
+        return ((data[idx] & 8191L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return ((data[idx] & 36028797018963967L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 5) & 144115188075855871L;
+      case 59:
+        return ((data[idx] & 31L) << 52) | (data[1+idx] >>> 12);
+      case 52:
+        return ((data[idx] & 4095L) << 45) | (data[1+idx] >>> 19);
+      case 45:
+        return ((data[idx] & 524287L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return ((data[idx] & 140737488355327L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return ((data[idx] & 18014398509481983L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 4) & 144115188075855871L;
+      case 60:
+        return ((data[idx] & 15L) << 53) | (data[1+idx] >>> 11);
+      case 53:
+        return ((data[idx] & 2047L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return ((data[idx] & 9007199254740991L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 3) & 144115188075855871L;
+      case 61:
+        return ((data[idx] & 7L) << 54) | (data[1+idx] >>> 10);
+      case 54:
+        return ((data[idx] & 1023L) << 47) | (data[1+idx] >>> 17);
+      case 47:
+        return ((data[idx] & 131071L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return ((data[idx] & 35184372088831L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return ((data[idx] & 4503599627370495L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return (data[idx] >>> 2) & 144115188075855871L;
+      case 62:
+        return ((data[idx] & 3L) << 55) | (data[1+idx] >>> 9);
+      case 55:
+        return ((data[idx] & 511L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return ((data[idx] & 2251799813685247L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return (data[idx] >>> 1) & 144115188075855871L;
+      case 63:
+        return ((data[idx] & 1L) << 56) | (data[1+idx] >>> 8);
+      case 56:
+        return ((data[idx] & 255L) << 49) | (data[1+idx] >>> 15);
+      case 49:
+        return ((data[idx] & 32767L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return ((data[idx] & 8796093022207L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return ((data[idx] & 1125899906842623L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return data[idx] & 144115188075855871L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader58 extends Base {
+    public Reader58(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*58;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 6;
+      case 58:
+        return ((data[idx] & 63L) << 52) | (data[1+idx] >>> 12);
+      case 52:
+        return ((data[idx] & 4095L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return ((data[idx] & 18014398509481983L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 2) & 288230376151711743L;
+      case 62:
+        return ((data[idx] & 3L) << 56) | (data[1+idx] >>> 8);
+      case 56:
+        return ((data[idx] & 255L) << 50) | (data[1+idx] >>> 14);
+      case 50:
+        return ((data[idx] & 16383L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return ((data[idx] & 1125899906842623L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return ((data[idx] & 72057594037927935L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 4) & 288230376151711743L;
+      case 60:
+        return ((data[idx] & 15L) << 54) | (data[1+idx] >>> 10);
+      case 54:
+        return ((data[idx] & 1023L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return ((data[idx] & 4503599627370495L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return data[idx] & 288230376151711743L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader59 extends Base {
+    public Reader59(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*59;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 5;
+      case 59:
+        return ((data[idx] & 31L) << 54) | (data[1+idx] >>> 10);
+      case 54:
+        return ((data[idx] & 1023L) << 49) | (data[1+idx] >>> 15);
+      case 49:
+        return ((data[idx] & 32767L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return ((data[idx] & 35184372088831L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return ((data[idx] & 1125899906842623L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return ((data[idx] & 36028797018963967L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return (data[idx] >>> 1) & 576460752303423487L;
+      case 63:
+        return ((data[idx] & 1L) << 58) | (data[1+idx] >>> 6);
+      case 58:
+        return ((data[idx] & 63L) << 53) | (data[1+idx] >>> 11);
+      case 53:
+        return ((data[idx] & 2047L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 43) | (data[1+idx] >>> 21);
+      case 43:
+        return ((data[idx] & 2097151L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return ((data[idx] & 2251799813685247L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return ((data[idx] & 72057594037927935L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return (data[idx] >>> 2) & 576460752303423487L;
+      case 62:
+        return ((data[idx] & 3L) << 57) | (data[1+idx] >>> 7);
+      case 57:
+        return ((data[idx] & 127L) << 52) | (data[1+idx] >>> 12);
+      case 52:
+        return ((data[idx] & 4095L) << 47) | (data[1+idx] >>> 17);
+      case 47:
+        return ((data[idx] & 131071L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return ((data[idx] & 140737488355327L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return ((data[idx] & 4503599627370495L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return ((data[idx] & 144115188075855871L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 3) & 576460752303423487L;
+      case 61:
+        return ((data[idx] & 7L) << 56) | (data[1+idx] >>> 8);
+      case 56:
+        return ((data[idx] & 255L) << 51) | (data[1+idx] >>> 13);
+      case 51:
+        return ((data[idx] & 8191L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return ((data[idx] & 8796093022207L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return ((data[idx] & 9007199254740991L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return ((data[idx] & 288230376151711743L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 4) & 576460752303423487L;
+      case 60:
+        return ((data[idx] & 15L) << 55) | (data[1+idx] >>> 9);
+      case 55:
+        return ((data[idx] & 511L) << 50) | (data[1+idx] >>> 14);
+      case 50:
+        return ((data[idx] & 16383L) << 45) | (data[1+idx] >>> 19);
+      case 45:
+        return ((data[idx] & 524287L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return ((data[idx] & 562949953421311L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return ((data[idx] & 18014398509481983L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return data[idx] & 576460752303423487L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader60 extends Base {
+    public Reader60(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*60;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 4;
+      case 60:
+        return ((data[idx] & 15L) << 56) | (data[1+idx] >>> 8);
+      case 56:
+        return ((data[idx] & 255L) << 52) | (data[1+idx] >>> 12);
+      case 52:
+        return ((data[idx] & 4095L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return ((data[idx] & 4503599627370495L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return ((data[idx] & 72057594037927935L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return data[idx] & 1152921504606846975L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader61 extends Base {
+    public Reader61(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*61;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 3;
+      case 61:
+        return ((data[idx] & 7L) << 58) | (data[1+idx] >>> 6);
+      case 58:
+        return ((data[idx] & 63L) << 55) | (data[1+idx] >>> 9);
+      case 55:
+        return ((data[idx] & 511L) << 52) | (data[1+idx] >>> 12);
+      case 52:
+        return ((data[idx] & 4095L) << 49) | (data[1+idx] >>> 15);
+      case 49:
+        return ((data[idx] & 32767L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 43) | (data[1+idx] >>> 21);
+      case 43:
+        return ((data[idx] & 2097151L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return ((data[idx] & 35184372088831L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return ((data[idx] & 2251799813685247L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return ((data[idx] & 18014398509481983L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return ((data[idx] & 144115188075855871L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return ((data[idx] & 1152921504606846975L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return (data[idx] >>> 2) & 2305843009213693951L;
+      case 62:
+        return ((data[idx] & 3L) << 59) | (data[1+idx] >>> 5);
+      case 59:
+        return ((data[idx] & 31L) << 56) | (data[1+idx] >>> 8);
+      case 56:
+        return ((data[idx] & 255L) << 53) | (data[1+idx] >>> 11);
+      case 53:
+        return ((data[idx] & 2047L) << 50) | (data[1+idx] >>> 14);
+      case 50:
+        return ((data[idx] & 16383L) << 47) | (data[1+idx] >>> 17);
+      case 47:
+        return ((data[idx] & 131071L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return ((data[idx] & 140737488355327L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return ((data[idx] & 1125899906842623L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return ((data[idx] & 9007199254740991L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return ((data[idx] & 72057594037927935L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return ((data[idx] & 576460752303423487L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return (data[idx] >>> 1) & 2305843009213693951L;
+      case 63:
+        return ((data[idx] & 1L) << 60) | (data[1+idx] >>> 4);
+      case 60:
+        return ((data[idx] & 15L) << 57) | (data[1+idx] >>> 7);
+      case 57:
+        return ((data[idx] & 127L) << 54) | (data[1+idx] >>> 10);
+      case 54:
+        return ((data[idx] & 1023L) << 51) | (data[1+idx] >>> 13);
+      case 51:
+        return ((data[idx] & 8191L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 45) | (data[1+idx] >>> 19);
+      case 45:
+        return ((data[idx] & 524287L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return ((data[idx] & 8796093022207L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return ((data[idx] & 562949953421311L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return ((data[idx] & 4503599627370495L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return ((data[idx] & 36028797018963967L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return ((data[idx] & 288230376151711743L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return data[idx] & 2305843009213693951L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader62 extends Base {
+    public Reader62(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*62;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 2;
+      case 62:
+        return ((data[idx] & 3L) << 60) | (data[1+idx] >>> 4);
+      case 60:
+        return ((data[idx] & 15L) << 58) | (data[1+idx] >>> 6);
+      case 58:
+        return ((data[idx] & 63L) << 56) | (data[1+idx] >>> 8);
+      case 56:
+        return ((data[idx] & 255L) << 54) | (data[1+idx] >>> 10);
+      case 54:
+        return ((data[idx] & 1023L) << 52) | (data[1+idx] >>> 12);
+      case 52:
+        return ((data[idx] & 4095L) << 50) | (data[1+idx] >>> 14);
+      case 50:
+        return ((data[idx] & 16383L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return ((data[idx] & 1125899906842623L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return ((data[idx] & 4503599627370495L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return ((data[idx] & 18014398509481983L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return ((data[idx] & 72057594037927935L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return ((data[idx] & 288230376151711743L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return ((data[idx] & 1152921504606846975L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return data[idx] & 4611686018427387903L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+  final static class Reader63 extends Base {
+    public Reader63(long[] data, long maxValue) {
+      super(data, maxValue);
+    }
+    public long get(int pos) {
+      final long bit = pos*63;
+      final int idx = (int) (bit>>6);
+      switch((int) (bit & 63)) {
+      case 0:
+        return data[idx] >>> 1;
+      case 63:
+        return ((data[idx] & 1L) << 62) | (data[1+idx] >>> 2);
+      case 62:
+        return ((data[idx] & 3L) << 61) | (data[1+idx] >>> 3);
+      case 61:
+        return ((data[idx] & 7L) << 60) | (data[1+idx] >>> 4);
+      case 60:
+        return ((data[idx] & 15L) << 59) | (data[1+idx] >>> 5);
+      case 59:
+        return ((data[idx] & 31L) << 58) | (data[1+idx] >>> 6);
+      case 58:
+        return ((data[idx] & 63L) << 57) | (data[1+idx] >>> 7);
+      case 57:
+        return ((data[idx] & 127L) << 56) | (data[1+idx] >>> 8);
+      case 56:
+        return ((data[idx] & 255L) << 55) | (data[1+idx] >>> 9);
+      case 55:
+        return ((data[idx] & 511L) << 54) | (data[1+idx] >>> 10);
+      case 54:
+        return ((data[idx] & 1023L) << 53) | (data[1+idx] >>> 11);
+      case 53:
+        return ((data[idx] & 2047L) << 52) | (data[1+idx] >>> 12);
+      case 52:
+        return ((data[idx] & 4095L) << 51) | (data[1+idx] >>> 13);
+      case 51:
+        return ((data[idx] & 8191L) << 50) | (data[1+idx] >>> 14);
+      case 50:
+        return ((data[idx] & 16383L) << 49) | (data[1+idx] >>> 15);
+      case 49:
+        return ((data[idx] & 32767L) << 48) | (data[1+idx] >>> 16);
+      case 48:
+        return ((data[idx] & 65535L) << 47) | (data[1+idx] >>> 17);
+      case 47:
+        return ((data[idx] & 131071L) << 46) | (data[1+idx] >>> 18);
+      case 46:
+        return ((data[idx] & 262143L) << 45) | (data[1+idx] >>> 19);
+      case 45:
+        return ((data[idx] & 524287L) << 44) | (data[1+idx] >>> 20);
+      case 44:
+        return ((data[idx] & 1048575L) << 43) | (data[1+idx] >>> 21);
+      case 43:
+        return ((data[idx] & 2097151L) << 42) | (data[1+idx] >>> 22);
+      case 42:
+        return ((data[idx] & 4194303L) << 41) | (data[1+idx] >>> 23);
+      case 41:
+        return ((data[idx] & 8388607L) << 40) | (data[1+idx] >>> 24);
+      case 40:
+        return ((data[idx] & 16777215L) << 39) | (data[1+idx] >>> 25);
+      case 39:
+        return ((data[idx] & 33554431L) << 38) | (data[1+idx] >>> 26);
+      case 38:
+        return ((data[idx] & 67108863L) << 37) | (data[1+idx] >>> 27);
+      case 37:
+        return ((data[idx] & 134217727L) << 36) | (data[1+idx] >>> 28);
+      case 36:
+        return ((data[idx] & 268435455L) << 35) | (data[1+idx] >>> 29);
+      case 35:
+        return ((data[idx] & 536870911L) << 34) | (data[1+idx] >>> 30);
+      case 34:
+        return ((data[idx] & 1073741823L) << 33) | (data[1+idx] >>> 31);
+      case 33:
+        return ((data[idx] & 2147483647L) << 32) | (data[1+idx] >>> 32);
+      case 32:
+        return ((data[idx] & 4294967295L) << 31) | (data[1+idx] >>> 33);
+      case 31:
+        return ((data[idx] & 8589934591L) << 30) | (data[1+idx] >>> 34);
+      case 30:
+        return ((data[idx] & 17179869183L) << 29) | (data[1+idx] >>> 35);
+      case 29:
+        return ((data[idx] & 34359738367L) << 28) | (data[1+idx] >>> 36);
+      case 28:
+        return ((data[idx] & 68719476735L) << 27) | (data[1+idx] >>> 37);
+      case 27:
+        return ((data[idx] & 137438953471L) << 26) | (data[1+idx] >>> 38);
+      case 26:
+        return ((data[idx] & 274877906943L) << 25) | (data[1+idx] >>> 39);
+      case 25:
+        return ((data[idx] & 549755813887L) << 24) | (data[1+idx] >>> 40);
+      case 24:
+        return ((data[idx] & 1099511627775L) << 23) | (data[1+idx] >>> 41);
+      case 23:
+        return ((data[idx] & 2199023255551L) << 22) | (data[1+idx] >>> 42);
+      case 22:
+        return ((data[idx] & 4398046511103L) << 21) | (data[1+idx] >>> 43);
+      case 21:
+        return ((data[idx] & 8796093022207L) << 20) | (data[1+idx] >>> 44);
+      case 20:
+        return ((data[idx] & 17592186044415L) << 19) | (data[1+idx] >>> 45);
+      case 19:
+        return ((data[idx] & 35184372088831L) << 18) | (data[1+idx] >>> 46);
+      case 18:
+        return ((data[idx] & 70368744177663L) << 17) | (data[1+idx] >>> 47);
+      case 17:
+        return ((data[idx] & 140737488355327L) << 16) | (data[1+idx] >>> 48);
+      case 16:
+        return ((data[idx] & 281474976710655L) << 15) | (data[1+idx] >>> 49);
+      case 15:
+        return ((data[idx] & 562949953421311L) << 14) | (data[1+idx] >>> 50);
+      case 14:
+        return ((data[idx] & 1125899906842623L) << 13) | (data[1+idx] >>> 51);
+      case 13:
+        return ((data[idx] & 2251799813685247L) << 12) | (data[1+idx] >>> 52);
+      case 12:
+        return ((data[idx] & 4503599627370495L) << 11) | (data[1+idx] >>> 53);
+      case 11:
+        return ((data[idx] & 9007199254740991L) << 10) | (data[1+idx] >>> 54);
+      case 10:
+        return ((data[idx] & 18014398509481983L) << 9) | (data[1+idx] >>> 55);
+      case 9:
+        return ((data[idx] & 36028797018963967L) << 8) | (data[1+idx] >>> 56);
+      case 8:
+        return ((data[idx] & 72057594037927935L) << 7) | (data[1+idx] >>> 57);
+      case 7:
+        return ((data[idx] & 144115188075855871L) << 6) | (data[1+idx] >>> 58);
+      case 6:
+        return ((data[idx] & 288230376151711743L) << 5) | (data[1+idx] >>> 59);
+      case 5:
+        return ((data[idx] & 576460752303423487L) << 4) | (data[1+idx] >>> 60);
+      case 4:
+        return ((data[idx] & 1152921504606846975L) << 3) | (data[1+idx] >>> 61);
+      case 3:
+        return ((data[idx] & 2305843009213693951L) << 2) | (data[1+idx] >>> 62);
+      case 2:
+        return ((data[idx] & 4611686018427387903L) << 1) | (data[1+idx] >>> 63);
+      case 1:
+        return data[idx] & 9223372036854775807L;
+      }
+
+      // unreachable, but compiler disagrees
+      return 0;
+    }
+  }
+}
Index: src/java/org/apache/lucene/util/packed/Direct64.java
===================================================================
--- src/java/org/apache/lucene/util/packed/Direct64.java	Mon Feb 22 08:42:35 CET 2010
+++ src/java/org/apache/lucene/util/packed/Direct64.java	Mon Feb 22 08:42:35 CET 2010
@@ -0,0 +1,79 @@
+package org.apache.lucene.util.packed;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.util.RamUsageEstimator;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Direct wrapping of 32 bit values to a backing array of ints.
+ */
+class Direct64 extends PackedInts.ReaderImpl
+        implements PackedInts.Mutable {
+  private long[] blocks;
+  private static final int BITS_PER_VALUE = 64;
+
+  public Direct64(int valueCount) {
+    super(valueCount, BITS_PER_VALUE);
+    blocks = new long[valueCount];
+  }
+
+  public Direct64(IndexInput in, int valueCount) throws IOException {
+    super(valueCount, BITS_PER_VALUE);
+    long[] blocks = new long[valueCount];
+    for(int i=0;i<valueCount;i++) {
+      blocks[i] = in.readLong();
+    }
+
+    this.blocks = blocks;
+  }
+
+
+  /**
+   * Creates an array backed by the given blocks.
+   * </p><p>
+   * Note: The blocks are used directly, so changes to the given block will
+   * affect the structure.
+   * @param blocks   used as the internal backing array.
+   */
+  public Direct64(long[] blocks) {
+    super(blocks.length, BITS_PER_VALUE);
+    this.blocks = blocks;
+  }
+
+  public long get(final int index) {
+    return blocks[index];
+  }
+
+  public void set(final int index, final long value) {
+    blocks[index] = value;
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER +
+            blocks.length * RamUsageEstimator.NUM_BYTES_LONG;
+  }
+
+  public void clear() {
+    Arrays.fill(blocks, 0L);
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/packed/package.html
===================================================================
--- src/java/org/apache/lucene/util/packed/package.html	Mon Feb 22 08:23:22 CET 2010
+++ src/java/org/apache/lucene/util/packed/package.html	Mon Feb 22 08:23:22 CET 2010
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head></head>
+<body bgcolor="white">
+
+<p>
+    The packed package provides random access capable arrays of positive longs.
+    The implementations provides different trade offs between memory usage and
+    access speed. The standard usage scenario is replacing large int or long
+    arrays in order to reduce the memory footprint.
+</p><p>
+    The main access point is the {@link PackedInts} factory.
+</p>
+
+</body>
+</html>
\ No newline at end of file
Index: src/java/org/apache/lucene/util/packed/Packed32.java
===================================================================
--- src/java/org/apache/lucene/util/packed/Packed32.java	Mon Mar 01 13:51:02 CET 2010
+++ src/java/org/apache/lucene/util/packed/Packed32.java	Mon Mar 01 13:51:02 CET 2010
@@ -0,0 +1,219 @@
+package org.apache.lucene.util.packed;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.util.RamUsageEstimator;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Space optimized random access capable array of values with a fixed number of
+ * bits. The maximum number of bits/value is 31. Use {@link Packed64} for higher
+ * numbers.
+ * </p><p>
+ * The implementation strives to avoid conditionals and expensive operations,
+ * sacrificing code clarity to achieve better performance.
+ */
+class Packed32 extends PackedInts.ReaderImpl implements PackedInts.Mutable {
+  static final int BLOCK_SIZE = 32; // 32 = int, 64 = long
+  static final int BLOCK_BITS = 5; // The #bits representing BLOCK_SIZE
+  static final int MOD_MASK = BLOCK_SIZE - 1; // x % BLOCK_SIZE
+
+  private static final int ENTRY_SIZE = BLOCK_SIZE + 1;
+  private static final int FAC_BITPOS = 3;
+
+  /*
+   * In order to make an efficient value-getter, conditionals should be
+   * avoided. A value can be positioned inside of a block, requiring shifting
+   * left or right or it can span two blocks, requiring a left-shift on the
+   * first block and a right-shift on the right block.
+   * </p><p>
+   * By always shifting the first block both left and right, we get exactly
+   * the right bits. By always shifting the second block right and applying
+   * a mask, we get the right bits there. After that, we | the two bitsets.
+  */
+  private static final int[][] SHIFTS =
+          new int[ENTRY_SIZE][ENTRY_SIZE * FAC_BITPOS];
+  private static final int[][] MASKS = new int[ENTRY_SIZE][ENTRY_SIZE];
+
+  static { // Generate shifts
+    for (int elementBits = 1 ; elementBits <= BLOCK_SIZE ; elementBits++) {
+      for (int bitPos = 0 ; bitPos < BLOCK_SIZE ; bitPos++) {
+        int[] currentShifts = SHIFTS[elementBits];
+        int base = bitPos * FAC_BITPOS;
+        currentShifts[base    ] = bitPos;
+        currentShifts[base + 1] = BLOCK_SIZE - elementBits;
+        if (bitPos <= BLOCK_SIZE - elementBits) { // Single block
+          currentShifts[base + 2] = 0;
+          MASKS[elementBits][bitPos] = 0;
+        } else { // Two blocks
+          int rBits = elementBits - (BLOCK_SIZE - bitPos);
+          currentShifts[base + 2] = BLOCK_SIZE - rBits;
+          MASKS[elementBits][bitPos] = ~(~0 << rBits);
+        }
+      }
+    }
+  }
+
+  /*
+   * The setter requires more masking than the getter.
+  */
+  private static final int[][] WRITE_MASKS =
+          new int[ENTRY_SIZE][ENTRY_SIZE * FAC_BITPOS];
+  static {
+    for (int elementBits = 1 ; elementBits <= BLOCK_SIZE ; elementBits++) {
+      int elementPosMask = ~(~0 << elementBits);
+      int[] currentShifts = SHIFTS[elementBits];
+      int[] currentMasks = WRITE_MASKS[elementBits];
+      for (int bitPos = 0 ; bitPos < BLOCK_SIZE ; bitPos++) {
+        int base = bitPos * FAC_BITPOS;
+        currentMasks[base  ] =~((elementPosMask
+                << currentShifts[base + 1])
+                >>> currentShifts[base]);
+        currentMasks[base+1] = ~(elementPosMask
+                << currentShifts[base + 2]);
+        currentMasks[base+2] = currentShifts[base + 2] == 0 ? 0 : ~0;
+      }
+    }
+  }
+
+  /* The bits */
+  private int[] blocks;
+
+  // Cached calculations
+  private int maxPos;      // blocks.length * BLOCK_SIZE / bitsPerValue - 1
+  private int[] shifts;    // The shifts for the current bitsPerValue
+  private int[] readMasks;
+  private int[] writeMasks;
+
+  /**
+   * Creates an array with the internal structures adjusted for the given
+   * limits and initialized to 0.
+   * @param valueCount   the number of elements.
+   * @param bitsPerValue the number of bits available for any given value.
+   *        Note: bitsPerValue >32 is not supported by this implementation.
+   */
+  public Packed32(int valueCount, int bitsPerValue) {
+    this(new int[(int)(((long)valueCount) * bitsPerValue / BLOCK_SIZE + 2)],
+            valueCount, bitsPerValue);
+  }
+
+  /**
+   * Creates an array with content retrieved from the given IndexInput.
+   * @param in       an IndexInput, positioned at the start of Packed64-content.
+   * @param valueCount  the number of elements.
+   * @param bitsPerValue the number of bits available for any given value.
+   * @throws java.io.IOException if the values for the backing array could not
+   *                             be retrieved.
+   */
+  public Packed32(IndexInput in, int valueCount, int bitsPerValue)
+                                                            throws IOException {
+    super(valueCount, bitsPerValue);
+    int size = size(bitsPerValue, valueCount);
+    blocks = new int[size + 1]; // +1 due to non-conditional tricks
+    for(int i = 0 ; i < size ; i++) {
+      blocks[i] = in.readInt();
+    }
+    if (size % 2 == 1) {
+      in.readInt(); // Align to long
+    }
+    updateCached();
+  }
+
+  private static int size(int bitsPerValue, int valueCount) {
+    final long totBitCount = (long) valueCount * bitsPerValue;
+    return (int) (totBitCount/32 + ((totBitCount % 32 == 0 ) ? 0:1));
+  }
+
+
+  /**
+   * Creates an array backed by the given blocks.
+   * </p><p>
+   * Note: The blocks are used directly, so changes to the given block will
+   * affect the Packed32-structure.
+   * @param blocks   used as the internal backing array.
+   * @param valueCount   the number of values.
+   * @param bitsPerValue the number of bits available for any given value.
+   *        Note: bitsPerValue >32 is not supported by this implementation.
+   */
+  public Packed32(int[] blocks, int valueCount, int bitsPerValue) {
+    // TODO: Check that blocks.length is sufficient for holding length values
+    super(valueCount, bitsPerValue);
+    if (bitsPerValue > 31) {
+      throw new IllegalArgumentException(String.format(
+              "This array only supports values of 31 bits or less. The "
+                      + "required number of bits was %d. The Packed64 "
+                      + "implementation allows values with more than 31 bits",
+              bitsPerValue));
+    }
+    this.blocks = blocks;
+    updateCached();
+  }
+
+  private void updateCached() {
+    readMasks = MASKS[bitsPerValue];
+    maxPos = (int)((((long)blocks.length) * BLOCK_SIZE / bitsPerValue) - 2);
+    shifts = SHIFTS[bitsPerValue];
+    writeMasks = WRITE_MASKS[bitsPerValue];
+  }
+
+  /**
+   * @param index the position of the value.
+   * @return the value at the given index.
+   */
+  public long get(final int index) {
+    final long majorBitPos = index * bitsPerValue;
+    final int elementPos = (int)(majorBitPos >>> BLOCK_BITS); // / BLOCK_SIZE
+    final int bitPos =     (int)(majorBitPos & MOD_MASK); // % BLOCK_SIZE);
+
+    final int base = bitPos * FAC_BITPOS;
+
+    return ((blocks[elementPos] << shifts[base]) >>> shifts[base+1]) |
+            ((blocks[elementPos+1] >>> shifts[base+2]) & readMasks[bitPos]);
+  }
+
+  public void set(final int index, final long value) {
+    final int intValue = (int)value;
+    final long majorBitPos = index * bitsPerValue;
+    final int elementPos = (int)(majorBitPos >>> BLOCK_BITS); // / BLOCK_SIZE
+    final int bitPos =     (int)(majorBitPos & MOD_MASK); // % BLOCK_SIZE);
+    final int base = bitPos * FAC_BITPOS;
+
+    blocks[elementPos  ] = (blocks[elementPos  ] & writeMasks[base])
+            | (intValue << shifts[base + 1] >>> shifts[base]);
+    blocks[elementPos+1] = (blocks[elementPos+1] & writeMasks[base+1])
+            | ((intValue << shifts[base + 2])
+            & writeMasks[base+2]);
+  }
+
+  public void clear() {
+    Arrays.fill(blocks, 0);
+  }
+
+  public String toString() {
+    return "Packed32(bitsPerValue=" + bitsPerValue + ", maxPos=" + maxPos
+            + ", elements.length=" + blocks.length + ")";
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER
+            + blocks.length * RamUsageEstimator.NUM_BYTES_INT;
+  }
+}
Index: src/java/org/apache/lucene/util/packed/Aligned32.java
===================================================================
--- src/java/org/apache/lucene/util/packed/Aligned32.java	Fri Feb 26 13:28:33 CET 2010
+++ src/java/org/apache/lucene/util/packed/Aligned32.java	Fri Feb 26 13:28:33 CET 2010
@@ -0,0 +1,204 @@
+package org.apache.lucene.util.packed;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.util.RamUsageEstimator;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Medium space and speed trade off. No values crosses block boundaries.
+ * The maximum number of bits/value is 32.
+ * Use {@link Aligned64} for higher numbers.
+ * </p><p>
+ * The implementation strives to avoid conditionals and expensive operations,
+ * sacrificing code clarity to achieve better performance.
+ * </p><p>
+ * Space is optimally used within the boundaries of alignment, e.g.
+ * 7 bits/value fits 4 values/block for 32 bit and 7 values/block for 64 bit.
+ * Bits are packed left-aligned to be bit pattern compatible with other bit
+ * array implementations where possible.
+ */
+class Aligned32 extends PackedInts.ReaderImpl
+        implements PackedInts.Mutable {
+  static final int BLOCK_SIZE = 32; // 32 = int, 64 = long
+
+  private static final int ENTRY_SIZE = BLOCK_SIZE + 1;
+
+  /*
+   * A value is always positioned inside a single block, requiring a
+   * shift right to position the bits and a mask to extract them.
+  */
+  private static final int[][] SHIFTS = new int[ENTRY_SIZE][ENTRY_SIZE];
+  private static final int[] READ_MASKS = new int[ENTRY_SIZE];
+
+  static { // Generate shifts
+      for (int elementBits = 1 ; elementBits <= BLOCK_SIZE ; elementBits++) {
+          int[] currentShifts = SHIFTS[elementBits];
+          for (int bitPos = 0 ; bitPos < BLOCK_SIZE ; bitPos++) {
+              currentShifts[bitPos] = BLOCK_SIZE - elementBits - bitPos;
+              READ_MASKS[elementBits]  = ~(~0 << elementBits);
+          }
+      }
+  }
+
+  /*
+   * Setting a value requires clearing the destination bits with a mask, then
+   * shifting the value to the left and or'ing the two numbers.
+  */
+  private static final int[][] WRITE_MASKS = new int[ENTRY_SIZE][ENTRY_SIZE];
+  static {
+      for (int elementBits = 1 ; elementBits <= BLOCK_SIZE ; elementBits++) {
+          int elementPosMask = ~(~0 << elementBits);
+          int[] currentShifts = SHIFTS[elementBits];
+          int[] currentMasks = WRITE_MASKS[elementBits];
+          for (int bitPos = 0 ; bitPos < BLOCK_SIZE ; bitPos++) {
+              currentMasks[bitPos] = ~(elementPosMask
+                                       << currentShifts[bitPos]);
+          }
+      }
+  }
+
+  /* The bits */
+  private int[] blocks;
+
+  /* Cached values */
+  private int valuesPerBlock;
+  private int[] shifts;
+  private int readMask;
+  private int[] writeMasks;
+
+  /**
+   * Creates an array with the internal structures adjusted for the given
+   * limits and initialized to 0.
+   * @param valueCount   the number of values.
+   * @param bitsPerValue the number of bits available for any given value.
+   */
+  public Aligned32(int valueCount, int bitsPerValue) {
+    super(valueCount, bitsPerValue);
+    if (bitsPerValue > 32) {
+      throw new IllegalArgumentException(String.format(
+              "This array only supports values of 32 bits or less. The "
+                      + "required number of bits was %d. The Aligned64 "
+                      + "implementation allows values with more than 32 bits",
+              bitsPerValue));
+    }
+    blocks = new int[size(valueCount, bitsPerValue)];
+    updateCached();
+  }
+
+  private static int size(int valueCount, int bitsPerValue) {
+    int valuesPerBlock = BLOCK_SIZE / bitsPerValue;
+    return valueCount == 0 ? 0 : (valueCount-1) / valuesPerBlock + 1;
+  }
+
+  /**
+   * Creates an array with content retrieved from the given IndexInput.
+   * @param in       an IndexInput, positioned at the start of Packed64-content.
+   * @param valueCount  the number of elements.
+   * @param bitsPerValue the number of bits available for any given value.
+   * @throws java.io.IOException if the values for the backing array could not
+   *                             be retrieved.
+   */
+  public Aligned32(IndexInput in, int valueCount, int bitsPerValue)
+                                                            throws IOException {
+    super(valueCount, bitsPerValue);
+    int size = size(valueCount, bitsPerValue);
+    blocks = new int[size];
+    for(int i = 0 ; i < size ; i++) {
+      blocks[i] = in.readInt();
+//      System.out.println("Reading  @bit32: " + Integer.toBinaryString((blocks[i])) + " (" + blocks[i] + ")");
+    }
+    if (size % 2 == 1) {
+      in.readInt(); // Align to long
+    }
+    in.readLong(); // Packed compatibility
+    updateCached();
+  }
+
+
+  /**
+   * Creates an array backed by the given blocks.
+   * </p><p>
+   * Note: The blocks are used directly, so changes to the given block will
+   * affect the Packed32-structure.
+   * @param blocks     used as the internal backing array.
+   * @param valueCount the number of values.
+   * @param bitsPerValue the number of bits available for any given value.
+   */
+  public Aligned32(int[] blocks, int valueCount, int bitsPerValue) {
+    // TODO: Check that blocks.length is sufficient for holding length values
+    super(valueCount, bitsPerValue);
+    this.blocks = blocks;
+    updateCached();
+  }
+
+  private void updateCached() {
+    valuesPerBlock = BLOCK_SIZE / bitsPerValue;
+    shifts = SHIFTS[bitsPerValue];
+    readMask = READ_MASKS[bitsPerValue];
+    writeMasks = WRITE_MASKS[bitsPerValue];
+  }
+
+  /**
+   * @param index the position of the value.
+   * @return the value at the given index.
+   */
+  public long get(final int index) {
+    final int blockPos = index / valuesPerBlock;
+    final int bitPos = (index - (blockPos * valuesPerBlock)) * bitsPerValue;
+
+    return (blocks[blockPos] >>> shifts[bitPos]) & readMask;
+  }
+
+  public void set(final int index, final long value) {
+    final int intValue = (int)value;
+
+    final int blockPos = index / valuesPerBlock;
+    final int bitPos = (index - (blockPos * valuesPerBlock)) * bitsPerValue;
+
+    blocks[blockPos] = (blocks[blockPos] & writeMasks[bitPos])
+            | (intValue << shifts[bitPos]);
+  }
+
+  public void clear() {
+    Arrays.fill(blocks, 0);
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER
+            + blocks.length * RamUsageEstimator.NUM_BYTES_INT;
+  }
+
+  public String toString() {
+    return "Aligned32(" + valueCount + " values at "
+            + bitsPerValue + " bits/value)";
+  }
+
+  /**
+   * The backing array contains the bits for the values in this structure.
+   * The array is returned directly, so any changes will be reflected both ways.
+   * Expert use only.
+   * @return the backing array.
+   */
+  int[] getBackingArray() {
+    return blocks;
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/store/IndexInput.java
===================================================================
--- src/java/org/apache/lucene/store/IndexInput.java	(revision 895342)
+++ src/java/org/apache/lucene/store/IndexInput.java	Tue Feb 23 11:19:38 CET 2010
@@ -64,6 +64,13 @@
     readBytes(b, offset, len);
   }
 
+  /** Reads two bytes and returns a short.
+   * @see IndexOutput#writeByte(byte)
+   */
+  public short readShort() throws IOException {
+    return (short) (((readByte() & 0xFF) <<  8) |  (readByte() & 0xFF));
+  }
+
   /** Reads four bytes and returns an int.
    * @see IndexOutput#writeInt(int)
    */
Index: src/java/org/apache/lucene/util/RamUsageEstimator.java
===================================================================
--- src/java/org/apache/lucene/util/RamUsageEstimator.java	(revision 901710)
+++ src/java/org/apache/lucene/util/RamUsageEstimator.java	Fri Feb 26 23:29:36 CET 2010
@@ -35,6 +35,16 @@
  * estimate is complete.
  */
 public final class RamUsageEstimator {
+
+  public final static int NUM_BYTES_SHORT = 2;
+  public final static int NUM_BYTES_INT = 4;
+  public final static int NUM_BYTES_LONG = 8;
+  public final static int NUM_BYTES_FLOAT = 4;
+  public final static int NUM_BYTES_DOUBLE = 8;
+  public final static int NUM_BYTES_OBJ_HEADER = 8;
+  public final static int NUM_BYTES_OBJ_REF = Constants.JRE_IS_64BIT ? 8 : 4;
+  public final static int NUM_BYTES_ARRAY_HEADER = NUM_BYTES_OBJ_HEADER + NUM_BYTES_INT + NUM_BYTES_OBJ_REF;
+
   private MemoryModel memoryModel;
 
   private final Map<Object,Object> seen;
@@ -45,11 +55,6 @@
 
   public final static int NUM_BYTES_OBJECT_REF = Constants.JRE_IS_64BIT ? 8 : 4;
   public final static int NUM_BYTES_CHAR = 2;
-  public final static int NUM_BYTES_SHORT = 2;
-  public final static int NUM_BYTES_INT = 4;
-  public final static int NUM_BYTES_LONG = 8;
-  public final static int NUM_BYTES_FLOAT = 4;
-  public final static int NUM_BYTES_DOUBLE = 8;
 
   private boolean checkInterned;
 
Index: src/java/org/apache/lucene/util/packed/Direct8.java
===================================================================
--- src/java/org/apache/lucene/util/packed/Direct8.java	Mon Feb 22 08:42:35 CET 2010
+++ src/java/org/apache/lucene/util/packed/Direct8.java	Mon Feb 22 08:42:35 CET 2010
@@ -0,0 +1,86 @@
+package org.apache.lucene.util.packed;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.util.RamUsageEstimator;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Direct wrapping of 8 bit values to a backing array of bytes.
+ */
+class Direct8 extends PackedInts.ReaderImpl
+        implements PackedInts.Mutable {
+  private byte[] blocks;
+  private static final int BITS_PER_VALUE = 8;
+
+  public Direct8(int valueCount) {
+    super(valueCount, BITS_PER_VALUE);
+    blocks = new byte[valueCount];
+  }
+
+  public Direct8(IndexInput in, int valueCount)
+          throws IOException {
+    super(valueCount, BITS_PER_VALUE);
+    byte[] blocks = new byte[valueCount];
+    for(int i=0;i<valueCount;i++) {
+      blocks[i] = in.readByte();
+    }
+    final int mod = valueCount % 8;
+    if (mod != 0) {
+      final int pad = 8-mod;
+      // round out long
+      for(int i=0;i<pad;i++) {
+        in.readByte();
+      }
+    }
+
+    this.blocks = blocks;
+  }
+
+  /**
+   * Creates an array backed by the given blocks.
+   * </p><p>
+   * Note: The blocks are used directly, so changes to the given block will
+   * affect the structure.
+   * @param blocks used as the internal backing array.
+   */
+  public Direct8(byte[] blocks) {
+    super(blocks.length, BITS_PER_VALUE);
+    this.blocks = blocks;
+  }
+
+  public long get(final int index) {
+    return 0xFFL & blocks[index];
+  }
+
+  public void set(final int index, final long value) {
+    blocks[index] = (byte)(value & 0xFF);
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER + blocks.length;
+  }
+
+  public void clear() {
+    Arrays.fill(blocks, (byte)0);
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/packed/PackedIntsPerformance.java
===================================================================
--- src/java/org/apache/lucene/util/packed/PackedIntsPerformance.java	Mon Mar 01 14:20:08 CET 2010
+++ src/java/org/apache/lucene/util/packed/PackedIntsPerformance.java	Mon Mar 01 14:20:08 CET 2010
@@ -0,0 +1,281 @@
+package org.apache.lucene.util.packed;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.StringWriter;
+import java.util.*;
+
+/**
+ * Simple performance testing of PackedInts.'
+ * NOTE: This uses classes that are not to be committed to SVN
+ *       (Aligned* and GenBitReaders).
+ */
+public class PackedIntsPerformance {
+  public static void main(String[] args) {
+    long startTime = System.currentTimeMillis();
+    new PackedIntsPerformance().testSpeed();
+    System.out.println(
+            "\nTotal execution time: "
+            + (System.currentTimeMillis() - startTime) / 1000 + " seconds");
+  }
+
+  private int tests = 0;
+  private Map<String, Long> ms = new LinkedHashMap<String, Long>();
+
+  public void testSpeed() {
+    final int RUN_COUNT = 3;
+    final int SEED = 87;
+    final int[] VALUE_COUNTS = new int[]{
+            1000, 1000*1000, 10*1000*1000};
+    final int[] BITS_PER_VALUE = new int[]{
+            1, 3, 4, 7, 8, 9, 15, 16, 17, 28, 31, 32, 33, 47, 49, 63};
+    final int[] GET_COUNT = new int[]{10*1000*1000};
+    String BASE_HEADER = String.format("%12s%12s%12s",
+            "bitsPerValue", "valueCount", "getCount");
+
+    String oldHeader = null;
+
+    for (int bitsPerValue: BITS_PER_VALUE) {
+      for (int valueCount: VALUE_COUNTS) {
+        for (int getCount: GET_COUNT) {
+          List<PackedInts.Reader> packedInts =
+                  createPackedInts(valueCount, bitsPerValue);
+          String header = BASE_HEADER;
+          for (PackedInts.Reader packedInt: packedInts) {
+              header += String.format("%12s", getName(packedInt));
+          }
+          if (!header.equals(oldHeader)) {
+            mean();
+            System.out.println("\n" + header);
+            oldHeader = header;
+          }
+          measureSpeed(
+                  packedInts, valueCount, bitsPerValue, getCount,
+                  RUN_COUNT, SEED);
+        }
+      }
+    }
+    mean();
+  }
+
+  private void mean() {
+    if (ms.size() != 0) {
+      System.out.print("Mean:                               ");
+      for (Map.Entry<String, Long> entry: ms.entrySet()) {
+        System.out.print(String.format(
+                "%12s", entry.getValue() / tests));
+      }
+      System.out.println("");
+    }
+    ms.clear();
+    tests = 0;
+  }
+
+  private void measureSpeed(
+          List<? extends PackedInts.Reader> packedInts,
+          int valueCount, int bitsPerValue,
+          int getCount, int runCount, int seed) {
+    tests++;
+    StringWriter sw = new StringWriter(1000);
+    sw.append(String.format("%12d%12d%12s",
+            bitsPerValue, valueCount, getCount));
+
+    for (PackedInts.Reader packedInt: packedInts) {
+      long minTime = Long.MAX_VALUE;
+      for (int run = 0 ; run < runCount ; run++) {
+        Random random = new Random(seed);
+        long startTime = System.nanoTime();
+        for (int get = 0 ; get < getCount ; get++) {
+          packedInt.get(random.nextInt(valueCount));
+        }
+        minTime = Math.min(minTime, System.nanoTime() - startTime);
+      }
+      String key = getName(packedInt);
+      ms.put(key, ms.containsKey(key) ? ms.get(key) + minTime / 1000000 :
+              minTime / 1000000);
+      sw.append(String.format("%12d", minTime / 1000000));
+    }
+    System.out.println(sw.toString());
+  }
+
+  private static String getName(PackedInts.Reader reader) {
+    String name = reader.getClass().getSimpleName();
+    return name.startsWith("Reader") ? "Generated" : name;
+  }
+
+  // Copy-paste from TestPackedInts
+  private static List<PackedInts.Reader> createPackedInts(
+          int valueCount, int bitsPerValue) {
+    List<PackedInts.Reader> packedInts = new ArrayList<PackedInts.Reader>();
+    if (bitsPerValue <= 8) {
+      packedInts.add(new Direct8(valueCount));
+    }
+    if (bitsPerValue <= 16) {
+      packedInts.add(new Direct16(valueCount));
+    }
+    if (bitsPerValue <= 31) {
+      packedInts.add(new Packed32(valueCount, bitsPerValue));
+      packedInts.add(new Aligned32(valueCount, bitsPerValue));
+    }
+    if (bitsPerValue <= 32) {
+      packedInts.add(new Direct32(valueCount));
+    }
+    if (bitsPerValue <= 63) {
+      packedInts.add(new Packed64(valueCount, bitsPerValue));
+      packedInts.add(new Aligned64(valueCount, bitsPerValue));
+    }
+    packedInts.add(new Direct64(valueCount));
+    PackedInts.Reader generated = getGenerated(valueCount, bitsPerValue);
+    if (generated != null) {
+      packedInts.add(generated);
+    }
+    return packedInts;
+  }
+
+  private static PackedInts.Reader getGenerated(
+          int valueCount, int bitsPerValue) {
+
+    long maxValue = PackedInts.maxValue(bitsPerValue);
+    long[] data = new long[valueCount * bitsPerValue / 64 + 1];
+    switch(bitsPerValue) {
+    case 1:
+      return new GenBitReaders.Reader1(data, maxValue);
+    case 2:
+      return new GenBitReaders.Reader2(data, maxValue);
+    case 3:
+      return new GenBitReaders.Reader3(data, maxValue);
+    case 4:
+      return new GenBitReaders.Reader4(data, maxValue);
+    case 5:
+      return new GenBitReaders.Reader5(data, maxValue);
+    case 6:
+      return new GenBitReaders.Reader6(data, maxValue);
+    case 7:
+      return new GenBitReaders.Reader7(data, maxValue);
+    case 9:
+      return new GenBitReaders.Reader9(data, maxValue);
+    case 10:
+      return new GenBitReaders.Reader10(data, maxValue);
+    case 11:
+      return new GenBitReaders.Reader11(data, maxValue);
+    case 12:
+      return new GenBitReaders.Reader12(data, maxValue);
+    case 13:
+      return new GenBitReaders.Reader13(data, maxValue);
+    case 14:
+      return new GenBitReaders.Reader14(data, maxValue);
+    case 15:
+      return new GenBitReaders.Reader15(data, maxValue);
+    case 17:
+      return new GenBitReaders.Reader17(data, maxValue);
+    case 18:
+      return new GenBitReaders.Reader18(data, maxValue);
+    case 19:
+      return new GenBitReaders.Reader19(data, maxValue);
+    case 20:
+      return new GenBitReaders.Reader20(data, maxValue);
+    case 21:
+      return new GenBitReaders.Reader21(data, maxValue);
+    case 22:
+      return new GenBitReaders.Reader22(data, maxValue);
+    case 23:
+      return new GenBitReaders.Reader23(data, maxValue);
+    case 24:
+      return new GenBitReaders.Reader24(data, maxValue);
+    case 25:
+      return new GenBitReaders.Reader25(data, maxValue);
+    case 26:
+      return new GenBitReaders.Reader26(data, maxValue);
+    case 27:
+      return new GenBitReaders.Reader27(data, maxValue);
+    case 28:
+      return new GenBitReaders.Reader28(data, maxValue);
+    case 29:
+      return new GenBitReaders.Reader29(data, maxValue);
+    case 30:
+      return new GenBitReaders.Reader30(data, maxValue);
+    case 31:
+      return new GenBitReaders.Reader31(data, maxValue);
+    case 33:
+      return new GenBitReaders.Reader33(data, maxValue);
+    case 34:
+      return new GenBitReaders.Reader34(data, maxValue);
+    case 35:
+      return new GenBitReaders.Reader35(data, maxValue);
+    case 36:
+      return new GenBitReaders.Reader36(data, maxValue);
+    case 37:
+      return new GenBitReaders.Reader37(data, maxValue);
+    case 38:
+      return new GenBitReaders.Reader38(data, maxValue);
+    case 39:
+      return new GenBitReaders.Reader39(data, maxValue);
+    case 40:
+      return new GenBitReaders.Reader40(data, maxValue);
+    case 41:
+      return new GenBitReaders.Reader41(data, maxValue);
+    case 42:
+      return new GenBitReaders.Reader42(data, maxValue);
+    case 43:
+      return new GenBitReaders.Reader43(data, maxValue);
+    case 44:
+      return new GenBitReaders.Reader44(data, maxValue);
+    case 45:
+      return new GenBitReaders.Reader45(data, maxValue);
+    case 46:
+      return new GenBitReaders.Reader46(data, maxValue);
+    case 47:
+      return new GenBitReaders.Reader47(data, maxValue);
+    case 48:
+      return new GenBitReaders.Reader48(data, maxValue);
+    case 49:
+      return new GenBitReaders.Reader49(data, maxValue);
+    case 50:
+      return new GenBitReaders.Reader50(data, maxValue);
+    case 51:
+      return new GenBitReaders.Reader51(data, maxValue);
+    case 52:
+      return new GenBitReaders.Reader52(data, maxValue);
+    case 53:
+      return new GenBitReaders.Reader53(data, maxValue);
+    case 54:
+      return new GenBitReaders.Reader54(data, maxValue);
+    case 55:
+      return new GenBitReaders.Reader55(data, maxValue);
+    case 56:
+      return new GenBitReaders.Reader56(data, maxValue);
+    case 57:
+      return new GenBitReaders.Reader57(data, maxValue);
+    case 58:
+      return new GenBitReaders.Reader58(data, maxValue);
+    case 59:
+      return new GenBitReaders.Reader59(data, maxValue);
+    case 60:
+      return new GenBitReaders.Reader60(data, maxValue);
+    case 61:
+      return new GenBitReaders.Reader61(data, maxValue);
+    case 62:
+      return new GenBitReaders.Reader62(data, maxValue);
+    case 63:
+      return new GenBitReaders.Reader63(data, maxValue);
+    }
+
+    // unreachable, but compiler disagrees
+    return null;
+  }
+}
Index: src/java/org/apache/lucene/util/packed/PackedWriter.java
===================================================================
--- src/java/org/apache/lucene/util/packed/PackedWriter.java	Tue Feb 23 15:42:13 CET 2010
+++ src/java/org/apache/lucene/util/packed/PackedWriter.java	Tue Feb 23 15:42:13 CET 2010
@@ -0,0 +1,116 @@
+package org.apache.lucene.util.packed;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.store.IndexOutput;
+
+import java.io.IOException;
+
+// Packs high order byte first, to match
+// IndexOutput.writeInt/Long/Short byte order
+
+/**
+ * Generic writer for space-optimal packed values. The resulting bits can be
+ * used directly by Packed32, Packed64 and PackedDirect* and will always be
+ * long-aligned.
+ */
+class PackedWriter extends PackedInts.Writer {
+  private long pending;
+  private int pendingBitPos;
+
+  // masks[n-1] masks for bottom n bits
+  private final long[] masks;
+  private int written = 0;
+
+  // nocommit -- allow minValue too?  ie not just minValue==0
+
+  public PackedWriter(IndexOutput out, int valueCount, int bitsPerValue)
+                                                            throws IOException {
+
+    super(out, valueCount, bitsPerValue, PackedInts.PERSISTENCE.packed);
+
+    pendingBitPos = 64;
+    masks = new long[bitsPerValue - 1];
+
+    int v = 1;
+    for (int i = 0; i < bitsPerValue - 1; i++) {
+      v *= 2;
+      masks[i] = v - 1;
+    }
+  }
+
+  /**
+   * Do not call this after finish
+   */
+  @Override
+  public void add(long v) throws IOException {
+    assert v <= PackedInts.maxValue(bitsPerValue) : "v=" + v
+            + " maxValue=" + PackedInts.maxValue(bitsPerValue);
+    assert v >= 0;
+    //System.out.println("    packedw add v=" + v + " pendingBitPos=" + pendingBitPos);
+
+    // TODO
+    if (pendingBitPos >= bitsPerValue) {
+      // not split
+
+      // write-once, so we can |= w/o first masking to 0s
+      pending |= v << (pendingBitPos - bitsPerValue);
+      if (pendingBitPos == bitsPerValue) {
+        // flush
+        out.writeLong(pending);
+        pending = 0;
+        pendingBitPos = 64;
+      } else {
+        pendingBitPos -= bitsPerValue;
+      }
+
+    } else {
+      // split
+
+      // write top pendingBitPos bits of value into bottom bits of pending
+      pending |= (v >> (bitsPerValue - pendingBitPos)) & masks[pendingBitPos - 1];
+      //System.out.println("      part1 (v >> " + (bitsPerValue - pendingBitPos) + ") & " + masks[pendingBitPos-1]);
+
+      // flush
+      out.writeLong(pending);
+
+      // write bottom (bitsPerValue - pendingBitPos) bits of value into top bits of pending
+      pendingBitPos = 64 - bitsPerValue + pendingBitPos;
+      //System.out.println("      part2 v << " + pendingBitPos);
+      pending = (v << pendingBitPos);
+    }
+    written++;
+  }
+
+  @Override
+  public void finish() throws IOException {
+    while (written < valueCount) {
+      add(0L); // Auto flush
+    }
+
+    if (pendingBitPos != 64) {
+      out.writeLong(pending);
+    }
+    out.writeLong(0L); // Dummy to compensate for not using conditionals
+  }
+
+  public String toString() {
+    return "PackedWriter(written " + written + "/" + valueCount + " with "
+            + bitsPerValue + " bits/value)";
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/packed/Direct16.java
===================================================================
--- src/java/org/apache/lucene/util/packed/Direct16.java	Mon Feb 22 08:42:35 CET 2010
+++ src/java/org/apache/lucene/util/packed/Direct16.java	Mon Feb 22 08:42:35 CET 2010
@@ -0,0 +1,86 @@
+package org.apache.lucene.util.packed;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.util.RamUsageEstimator;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Direct wrapping of 16 bit values to a backing array of shorts.
+ */
+class Direct16 extends PackedInts.ReaderImpl
+        implements PackedInts.Mutable {
+  private short[] blocks;
+  private static final int BITS_PER_VALUE = 16;
+
+  public Direct16(int valueCount) {
+    super(valueCount, BITS_PER_VALUE);
+    blocks = new short[valueCount];
+  }
+
+  public Direct16(IndexInput in, int valueCount) throws IOException {
+    super(valueCount, BITS_PER_VALUE);
+    short[] blocks = new short[valueCount];
+    for(int i=0;i<valueCount;i++) {
+      blocks[i] = in.readShort();
+    }
+    final int mod = valueCount % 4;
+    if (mod != 0) {
+      final int pad = 4-mod;
+      // round out long
+      for(int i=0;i<pad;i++) {
+        in.readShort();
+      }
+    }
+
+    this.blocks = blocks;
+  }
+
+  /**
+   * Creates an array backed by the given blocks.
+   * </p><p>
+   * Note: The blocks are used directly, so changes to the given block will
+   * affect the structure.
+   * @param blocks   used as the internal backing array.
+   */
+  public Direct16(short[] blocks) {
+    super(blocks.length, BITS_PER_VALUE);
+    this.blocks = blocks;
+  }
+
+  public long get(final int index) {
+    return 0xFFFFL & blocks[index];
+  }
+
+  public void set(final int index, final long value) {
+    blocks[index] = (short)(value & 0xFFFF);
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER +
+            blocks.length * RamUsageEstimator.NUM_BYTES_SHORT;
+  }
+
+  public void clear() {
+    Arrays.fill(blocks, (short)0);
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/packed/Direct32.java
===================================================================
--- src/java/org/apache/lucene/util/packed/Direct32.java	Mon Feb 22 08:42:35 CET 2010
+++ src/java/org/apache/lucene/util/packed/Direct32.java	Mon Feb 22 08:42:35 CET 2010
@@ -0,0 +1,82 @@
+package org.apache.lucene.util.packed;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.util.RamUsageEstimator;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Direct wrapping of 32 bit values to a backing array of ints.
+ */
+class Direct32 extends PackedInts.ReaderImpl
+        implements PackedInts.Mutable {
+  private int[] blocks;
+  private static final int BITS_PER_VALUE = 32;
+
+  public Direct32(int valueCount) {
+    super(valueCount, BITS_PER_VALUE);
+    blocks = new int[valueCount];
+  }
+
+  public Direct32(IndexInput in, int valueCount) throws IOException {
+    super(valueCount, BITS_PER_VALUE);
+    int[] blocks = new int[valueCount];
+    for(int i=0;i<valueCount;i++) {
+      blocks[i] = in.readInt();
+    }
+    final int mod = valueCount % 2;
+    if (mod != 0) {
+      in.readInt();
+    }
+
+    this.blocks = blocks;
+  }
+
+  /**
+   * Creates an array backed by the given blocks.
+   * </p><p>
+   * Note: The blocks are used directly, so changes to the given block will
+   * affect the structure.
+   * @param blocks   used as the internal backing array.
+   */
+  public Direct32(int[] blocks) {
+    super(blocks.length, BITS_PER_VALUE);
+    this.blocks = blocks;
+  }
+
+  public long get(final int index) {
+    return 0xFFFFFFFFL & blocks[index];
+  }
+
+  public void set(final int index, final long value) {
+    blocks[index] = (int)(value & 0xFFFFFFFF);
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER +
+            blocks.length * RamUsageEstimator.NUM_BYTES_INT;
+  }
+
+  public void clear() {
+    Arrays.fill(blocks, 0);
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/BytesRef.java
===================================================================
--- src/java/org/apache/lucene/util/BytesRef.java	Fri Jan 22 12:58:35 CET 2010
+++ src/java/org/apache/lucene/util/BytesRef.java	Fri Jan 22 12:58:35 CET 2010
@@ -0,0 +1,170 @@
+package org.apache.lucene.util;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.UnsupportedEncodingException;
+
+// nocommit -- share w/ flex's TermRef
+public class BytesRef {
+
+  public byte[] bytes;
+  public int offset;
+  public int length;
+
+  public abstract static class Comparator {
+    abstract public int compare(BytesRef a, BytesRef b);
+  }
+
+  public BytesRef() {
+  }
+
+  /** Creates bytes ref, wrapping UTF8 bytes from the
+   *  provided string. */
+  public BytesRef(String s) {
+    try {
+      bytes = s.getBytes("UTF-8");
+    } catch (UnsupportedEncodingException uee) {
+      throw new RuntimeException(uee);
+    }
+    offset = 0;
+    length = bytes.length;
+  }
+
+  public BytesRef(BytesRef other) {
+    offset = 0;
+    length = other.length;
+    bytes = new byte[other.length];
+    System.arraycopy(other.bytes, other.offset, bytes, 0, length);
+  }
+
+  public boolean bytesEquals(BytesRef other) {
+    if (length == other.length) {
+      int upto = offset;
+      int otherUpto = other.offset;
+      final byte[] otherBytes = other.bytes;
+      for(int i=0;i<length;i++) {
+        if (bytes[upto++] != otherBytes[otherUpto++]) {
+          return false;
+        }
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  public String utf8ToString() {
+    try {
+      return new String(bytes, offset, length, "UTF8");
+    } catch (java.io.UnsupportedEncodingException uee) {
+      throw new RuntimeException(uee);
+    }
+  }
+
+  private final static Comparator straightComparator = new StraightComparator();
+
+  public static Comparator getStraightComparator() {
+    return straightComparator;
+  }
+
+  public static class StraightComparator extends Comparator {
+    public int compare(BytesRef a, BytesRef b) {
+      int aUpto = a.offset;
+      int bUpto = b.offset;
+      final int aStop;
+      if (a.length <= b.length) {
+        aStop = aUpto + a.length;
+      } else {
+        aStop = aUpto + b.length;
+      }
+      while(aUpto < aStop) {
+        final int cmp = a.bytes[aUpto++] - b.bytes[bUpto++];
+        if (cmp != 0) {
+          return cmp;
+        }
+      }
+      return a.length - b.length;
+    }
+  }
+
+  private final static Comparator utf8SortedAsUTF16SortOrder = new UTF8SortedAsUTF16Comparator();
+
+  public static Comparator getUTF8SortedAsUTF16Comparator() {
+    return utf8SortedAsUTF16SortOrder;
+  }
+
+  public static class UTF8SortedAsUTF16Comparator extends Comparator {
+    public int compare(BytesRef a, BytesRef b) {
+
+      final byte[] aBytes = a.bytes;
+      int aUpto = a.offset;
+      final byte[] bBytes = b.bytes;
+      int bUpto = b.offset;
+
+      final int aStop;
+      if (a.length < b.length) {
+        aStop = aUpto + a.length;
+      } else {
+        aStop = aUpto + b.length;
+      }
+
+      while(aUpto < aStop) {
+        int aByte = aBytes[aUpto++] & 0xff;
+        int bByte = bBytes[bUpto++] & 0xff;
+
+        if (aByte != bByte) {
+          // See http://icu-project.org/docs/papers/utf16_code_point_order.html#utf-8-in-utf-16-order
+          // We know the terms are not equal, but, we may
+          // have to carefully fixup the bytes at the
+          // difference to match UTF16's sort order:
+          if (aByte >= 0xee && bByte >= 0xee) {
+            if ((aByte & 0xfe) == 0xee) {
+              aByte += 0x10;
+            }
+            if ((bByte&0xfe) == 0xee) {
+              bByte += 0x10;
+            }
+          }
+          return aByte - bByte;
+        }
+      }
+
+      // One is a prefix of the other, or, they are equal:
+      return a.length - b.length;
+    }
+  }
+
+  // nocommit -- kinda hackish?  needed only (so far) for FieldComparator
+  private static class ComparableBytesRef implements Comparable {
+    private final BytesRef b;
+    private final Comparator c;
+    public ComparableBytesRef(BytesRef b, Comparator c) {
+      this.b = b;
+      this.c = c;
+    }
+
+    public int compareTo(Object other) {
+      final ComparableBytesRef o = (ComparableBytesRef) other;
+      return c.compare(b, o.b);
+    }
+  }
+
+  public static Comparable getComparableBytesRef(BytesRef b, Comparator c) {
+    return new ComparableBytesRef(b, c);
+  }
+}
Index: src/java/org/apache/lucene/util/packed/Packed64.java
===================================================================
--- src/java/org/apache/lucene/util/packed/Packed64.java	Fri Feb 26 13:29:32 CET 2010
+++ src/java/org/apache/lucene/util/packed/Packed64.java	Fri Feb 26 13:29:32 CET 2010
@@ -0,0 +1,210 @@
+package org.apache.lucene.util.packed;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.util.RamUsageEstimator;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Space optimized random access capable array of values with a fixed number of
+ * bits. For 32 bits/value and less, performance on 32 bit machines is not
+ * optimal. Consider using {@link Packed32} for such a setup.
+ * </p><p>
+ * The implementation strives to avoid conditionals and expensive operations,
+ * sacrificing code clarity to achieve better performance.
+ */
+class Packed64 extends PackedInts.ReaderImpl implements PackedInts.Mutable {
+  static final int BLOCK_SIZE = 64; // 32 = int, 64 = long
+  static final int BLOCK_BITS = 6; // The #bits representing BLOCK_SIZE
+  static final int MOD_MASK = BLOCK_SIZE - 1; // x % BLOCK_SIZE
+
+  private static final int ENTRY_SIZE = BLOCK_SIZE + 1;
+  private static final int FAC_BITPOS = 3;
+
+  /*
+   * In order to make an efficient value-getter, conditionals should be
+   * avoided. A value can be positioned inside of a block, requiring shifting
+   * left or right or it can span two blocks, requiring a left-shift on the
+   * first block and a right-shift on the right block.
+   * </p><p>
+   * By always shifting the first block both left and right, we get exactly
+   * the right bits. By always shifting the second block right and applying
+   * a mask, we get the right bits there. After that, we | the two bitsets.
+  */
+  private static final int[][] SHIFTS =
+          new int[ENTRY_SIZE][ENTRY_SIZE * FAC_BITPOS];
+          //new int[BLOCK_SIZE+1][BLOCK_SIZE][BLOCK_SIZE+1];
+  private static final long[][] MASKS = new long[ENTRY_SIZE][ENTRY_SIZE];
+
+  static { // Generate shifts
+      for (int elementBits = 1 ; elementBits <= BLOCK_SIZE ; elementBits++) {
+          for (int bitPos = 0 ; bitPos < BLOCK_SIZE ; bitPos++) {
+              int[] currentShifts = SHIFTS[elementBits];
+              int base = bitPos * FAC_BITPOS;
+              currentShifts[base    ] = bitPos;
+              currentShifts[base + 1] = BLOCK_SIZE - elementBits;
+              if (bitPos <= BLOCK_SIZE - elementBits) { // Single block
+                  currentShifts[base + 2] = 0;
+                  MASKS[elementBits][bitPos] = 0;
+              } else { // Two blocks
+                  int rBits = elementBits - (BLOCK_SIZE - bitPos);
+                  currentShifts[base + 2] = BLOCK_SIZE - rBits;
+                  MASKS[elementBits][bitPos] = ~(~0L << rBits);
+              }
+          }
+      }
+  }
+
+  /*
+   * The setter requires more masking than the getter.
+  */
+  private static final long[][] WRITE_MASKS =
+          new long[ENTRY_SIZE][ENTRY_SIZE * FAC_BITPOS];
+  static {
+      for (int elementBits = 1 ; elementBits <= BLOCK_SIZE ; elementBits++) {
+          long elementPosMask = ~(~0L << elementBits);
+          int[] currentShifts = SHIFTS[elementBits];
+          long[] currentMasks = WRITE_MASKS[elementBits];
+          for (int bitPos = 0 ; bitPos < BLOCK_SIZE ; bitPos++) {
+              int base = bitPos * FAC_BITPOS;
+              currentMasks[base  ] =~((elementPosMask
+                                 << currentShifts[base + 1])
+                                >>> currentShifts[base]);
+              currentMasks[base+1] = ~(elementPosMask
+                                 << currentShifts[base + 2]);
+              currentMasks[base+2] = currentShifts[base + 2] == 0 ? 0 : ~0;
+          }
+      }
+  }
+
+  /* The bits */
+  private long[] blocks;
+
+  // Cached calculations
+  private int maxPos;      // blocks.length * BLOCK_SIZE / elementBits - 1
+  private int[] shifts;    // The shifts for the current elementBits
+  private long[] readMasks;
+  private long[] writeMasks;
+
+  /**
+   * Creates an array with the internal structures adjusted for the given
+   * limits and initialized to 0.
+   * @param valueCount   the number of elements.
+   * @param bitsPerValue the number of bits available for any given value.
+   */
+  public Packed64(int valueCount, int bitsPerValue) {
+    // TODO: Test for edge-cases (2^31 values, 63 bitsPerValue)
+    // +2 due to the avoid-conditionals-trick. The last entry is always 0
+    this(new long[(int)((long)valueCount * bitsPerValue / BLOCK_SIZE + 2)],
+            valueCount, bitsPerValue);
+  }
+
+
+  /**
+   * Creates an array backed by the given blocks.
+   * </p><p>
+   * Note: The blocks are used directly, so changes to the given block will
+   * affect the Packed32-structure.
+   * @param blocks   used as the internal backing array. Not that the last
+   *                 element cannot be addressed directly.
+   * @param valueCount the number of values.
+   * @param bitsPerValue the number of bits available for any given value.
+   */
+  public Packed64(long[] blocks, int valueCount, int bitsPerValue) {
+    super(valueCount, bitsPerValue);
+    this.blocks = blocks;
+    updateCached();
+  }
+
+  /**
+   * Creates an array with content retrieved from the given IndexInput.
+   * @param in       an IndexInput, positioned at the start of Packed64-content.
+   * @param valueCount  the number of elements.
+   * @param bitsPerValue the number of bits available for any given value.
+   * @throws java.io.IOException if the values for the backing array could not
+   *                             be retrieved.
+   */
+  public Packed64(IndexInput in, int valueCount, int bitsPerValue)
+                                                            throws IOException {
+    super(valueCount, bitsPerValue);
+    int size = size(valueCount, bitsPerValue);
+    blocks = new long[size+1]; // +1 due to non-conditional tricks
+    for(int i=0;i<size;i++) {
+      blocks[i] = in.readLong();
+    }
+    updateCached();
+  }
+
+  private static int size(int valueCount, int bitsPerValue) {
+    final long totBitCount = (long) valueCount * bitsPerValue;
+    return (int)(totBitCount/64 + ((totBitCount % 64 == 0 ) ? 0:1));
+  }
+
+  private void updateCached() {
+    readMasks = MASKS[bitsPerValue];
+    shifts = SHIFTS[bitsPerValue];
+    writeMasks = WRITE_MASKS[bitsPerValue];
+    maxPos = (int)((((long)blocks.length) * BLOCK_SIZE / bitsPerValue) - 2);
+  }
+
+  /**
+   * @param index the position of the value.
+   * @return the value at the given index.
+   */
+  public long get(final int index) {
+    final long majorBitPos = index * bitsPerValue;
+    final int elementPos = (int)(majorBitPos >>> BLOCK_BITS); // / BLOCK_SIZE
+    final int bitPos =     (int)(majorBitPos & MOD_MASK); // % BLOCK_SIZE);
+
+    final int base = bitPos * FAC_BITPOS;
+
+    return ((blocks[elementPos] << shifts[base]) >>> shifts[base+1]) |
+            ((blocks[elementPos+1] >>> shifts[base+2]) & readMasks[bitPos]);
+  }
+
+  public void set(final int index, final long value) {
+    final long majorBitPos = index * bitsPerValue;
+    final int elementPos = (int)(majorBitPos >>> BLOCK_BITS); // / BLOCK_SIZE
+    final int bitPos =     (int)(majorBitPos & MOD_MASK); // % BLOCK_SIZE);
+    final int base = bitPos * FAC_BITPOS;
+
+    blocks[elementPos  ] = (blocks[elementPos  ] & writeMasks[base])
+                           | (value << shifts[base + 1] >>> shifts[base]);
+    blocks[elementPos+1] = (blocks[elementPos+1] & writeMasks[base+1])
+                           | ((value << shifts[base + 2]) & writeMasks[base+2]);
+  }
+
+  public String toString() {
+    return "Packed64(bitsPerValue=" + bitsPerValue + ", size="
+            + size() + ", maxPos=" + maxPos
+            + ", elements.length=" + blocks.length + ")";
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER
+            + blocks.length * RamUsageEstimator.NUM_BYTES_LONG;
+  }
+
+  public void clear() {
+    Arrays.fill(blocks, 0L);
+  }
+
+}
\ No newline at end of file
Index: src/test/org/apache/lucene/util/packed/TestPackedInts.java
===================================================================
--- src/test/org/apache/lucene/util/packed/TestPackedInts.java	Mon Mar 01 14:40:00 CET 2010
+++ src/test/org/apache/lucene/util/packed/TestPackedInts.java	Mon Mar 01 14:40:00 CET 2010
@@ -0,0 +1,265 @@
+package org.apache.lucene.util.packed;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.store.*;
+import org.apache.lucene.util.LuceneTestCase;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.io.IOException;
+
+public class TestPackedInts extends LuceneTestCase {
+
+/*  public void testBitsRequired() throws Exception {
+    assertEquals(61, PackedInts.bitsRequired((long)Math.pow(2, 61)-1));
+    assertEquals(61, PackedInts.bitsRequired(0x1FFFFFFFFFFFFFFFL));
+    assertEquals(62, PackedInts.bitsRequired(0x3FFFFFFFFFFFFFFFL));
+    assertEquals(63, PackedInts.bitsRequired(0x7FFFFFFFFFFFFFFFL));
+  } */
+
+  public void testMaxValues() throws Exception {
+    assertEquals("1 bit -> max == 1",
+            1, PackedInts.maxValue(1));
+    assertEquals("2 bit -> max == 3",
+            3, PackedInts.maxValue(2));
+    assertEquals("8 bit -> max == 255",
+            255, PackedInts.maxValue(8));
+    assertEquals("63 bit -> max == Long.MAX_VALUE",
+            Long.MAX_VALUE, PackedInts.maxValue(63));
+    assertEquals("64 bit -> max == Long.MAX_VALUE (same as for 63 bit)", 
+            Long.MAX_VALUE, PackedInts.maxValue(63));
+  }
+
+  public void testPackedInts() throws IOException {
+    Random rand = newRandom();
+    for(int iter=0;iter<50;iter++) {
+      long ceil = 2;
+      // nocommit -- need to get the 64 bit case working
+      for(int nbits=1;nbits<63;nbits++) {
+        final int valueCount = 100+rand.nextInt(500);
+        final Directory d = new MockRAMDirectory();
+
+        IndexOutput out = d.createOutput("out.bin");
+        PackedInts.Writer w = PackedInts.getWriter(
+                out, valueCount, nbits, PackedInts.STORAGE.packed);
+
+        final long[] values = new long[valueCount];
+        for(int i=0;i<valueCount;i++) {
+          long v = rand.nextLong() % ceil;
+          if (v < 0) {
+            v = -v;
+          }
+          values[i] = v;
+          w.add(values[i]);
+        }
+        w.finish();
+        out.close();
+
+        IndexInput in = d.openInput("out.bin");
+        PackedInts.Reader r = PackedInts.getReader(in);
+        for(int i=0;i<valueCount;i++) {
+          assertEquals("index=" + i + " ceil=" + ceil + " valueCount="
+                  + valueCount + " nbits=" + nbits + " for "
+                  + r.getClass().getSimpleName(), values[i], r.get(i));
+        }
+        in.close();
+        ceil *= 2;
+      }
+    }
+  }
+
+  public void testControlledEquality() {
+    final int VALUE_COUNT = 255;
+    final int BITS_PER_VALUE = 8;
+
+    List<PackedInts.Mutable> packedInts =
+            createPackedInts(VALUE_COUNT, BITS_PER_VALUE);
+    for (PackedInts.Mutable packedInt: packedInts) {
+      for (int i = 0 ; i < packedInt.size() ; i++) {
+        packedInt.set(i, i+1);
+      }
+    }
+    assertListEquality(packedInts);
+  }
+
+  public void testRandomEquality() {
+    final int[] VALUE_COUNTS = new int[]{0, 1, 5, 8, 100, 500};
+    final int MIN_BITS_PER_VALUE = 1;
+    final int MAX_BITS_PER_VALUE = 64;
+    final int RANDOM_SEED = 87;
+
+    for (int valueCount: VALUE_COUNTS) {
+      for (int bitsPerValue = MIN_BITS_PER_VALUE ;
+           bitsPerValue <= MAX_BITS_PER_VALUE ;
+           bitsPerValue++) {
+        assertRandomEquality(valueCount, bitsPerValue, RANDOM_SEED);
+      }
+    }
+  }
+
+  public void testRandomPersistenceEquality() {
+    final int[] VALUE_COUNTS = new int[]{0, 1, 5, 8, 100, 500};
+    final int MIN_BITS_PER_VALUE = 1;
+    final int MAX_BITS_PER_VALUE = 63;
+    final int RANDOM_SEED = 87;
+
+    for (int valueCount: VALUE_COUNTS) {
+      for (int bitsPerValue = MIN_BITS_PER_VALUE ;
+           bitsPerValue <= MAX_BITS_PER_VALUE ;
+           bitsPerValue++) {
+        assertRandomPersistenceEquality(valueCount, bitsPerValue, RANDOM_SEED);
+      }
+    }
+  }
+
+  /* ************************************************************************ */
+
+  /* ************************************************************************ */
+
+  private void assertRandomEquality(
+          int valueCount, int bitsPerValue, int randomSeed) {
+    List<PackedInts.Mutable> packedInts =
+            createPackedInts(valueCount, bitsPerValue);
+    for (PackedInts.Mutable packedInt: packedInts) {
+      try {
+        fill(packedInt, (long)(Math.pow(2, bitsPerValue)-1), randomSeed);
+      } catch (Exception e) {
+        e.printStackTrace(System.err);
+        fail(String.format(
+                "Exception while filling %s: valueCount=%d, bitsPerValue=%s",
+                packedInt.getClass().getSimpleName(),
+                valueCount, bitsPerValue));
+      }
+    }
+    assertListEquality(packedInts);
+  }
+
+  private void assertRandomPersistenceEquality(
+          int valueCount, int bitsPerValue, int randomSeed) {
+    List<PackedInts.Reader> packedInts = new ArrayList<PackedInts.Reader>();
+    for (PackedInts.STORAGE storage: PackedInts.STORAGE.values()) {
+      try {
+        packedInts.add(writeAndRead(
+                valueCount, bitsPerValue, storage, PackedInts.BLOCK.bit32,
+                randomSeed));
+        packedInts.add(writeAndRead(
+                valueCount, bitsPerValue, storage, PackedInts.BLOCK.bit64,
+                randomSeed));
+      } catch (Exception e) {
+        e.printStackTrace(System.err);
+        fail(String.format(
+                "Exception while filling %s: valueCount=%d, bitsPerValue=%s",
+                storage, valueCount, bitsPerValue));
+      }
+    }
+    assertListEquality("valueCount=" + valueCount +", bitsPerValue="
+            + bitsPerValue, packedInts);
+  }
+
+  private PackedInts.Reader writeAndRead(
+          int valueCount, int bitsPerValue,
+          PackedInts.STORAGE storage, PackedInts.BLOCK block, int randomSeed)
+                                                            throws IOException {
+    long randMax = bitsPerValue >= 63 ?
+            Long.MAX_VALUE : PackedInts.maxValue(bitsPerValue)+1;
+    Random random = new Random(randomSeed);
+
+    final Directory d = new MockRAMDirectory();
+    IndexOutput out = d.createOutput("out.bin");
+    PackedInts.Writer w = PackedInts.getWriter(
+            out, valueCount, bitsPerValue, storage, block);
+
+//    System.out.println("Writer: " + w);
+
+    for (int i = 0 ; i < valueCount ; i++) {
+      w.add(Math.abs(random.nextLong() % randMax));
+    }
+    w.finish();
+    out.close();
+
+    IndexInput in = d.openInput("out.bin");
+    PackedInts.Reader reader = PackedInts.getReader(in);
+//    System.out.println("Reader: " + reader);
+    return reader;
+  }
+
+  private List<PackedInts.Mutable> createPackedInts(
+          int valueCount, int bitsPerValue) {
+    List<PackedInts.Mutable> packedInts = new ArrayList<PackedInts.Mutable>();
+    if (bitsPerValue <= 8) {
+      packedInts.add(new Direct8(valueCount));
+    }
+    if (bitsPerValue <= 16) {
+      packedInts.add(new Direct16(valueCount));
+    }
+    if (bitsPerValue <= 31) {
+      packedInts.add(new Packed32(valueCount, bitsPerValue));
+    }
+    if (bitsPerValue <= 32) {
+      packedInts.add(new Direct32(valueCount));
+    }
+    if (bitsPerValue <= 63) {
+      packedInts.add(new Packed64(valueCount, bitsPerValue));
+    }
+    packedInts.add(new Direct64(valueCount));
+    return packedInts;
+  }
+
+  private void fill(
+          PackedInts.Mutable packedInt, long maxValue, int randomSeed) {
+    maxValue++;
+    Random random = new Random(randomSeed);
+    for (int i = 0 ; i < packedInt.size() ; i++) {
+      long value = Math.abs(random.nextLong() % maxValue);
+      packedInt.set(i, value);
+      assertEquals(String.format(
+              "The set/get of the value at index %d should match for %s",
+              i, packedInt.getClass().getSimpleName()),
+              value, packedInt.get(i));
+    }
+  }
+
+  private void assertListEquality(
+          List<? extends PackedInts.Reader> packedInts) {
+    assertListEquality("", packedInts);
+  }
+    private void assertListEquality(
+            String message, List<? extends PackedInts.Reader> packedInts) {
+    if (packedInts.size() == 0) {
+      return;
+    }
+    PackedInts.Reader base = packedInts.get(0);
+    int valueCount = base.size();
+    for (PackedInts.Reader packedInt: packedInts) {
+      assertEquals(message + ". The number of values should be the same ",
+              valueCount, packedInt.size());
+    }
+    for (int i = 0 ; i < valueCount ; i++) {
+      for (int j = 1 ; j < packedInts.size() ; j++) {
+        assertEquals(String.format(
+                "%s. The value at index %d should be the same for %s and %s",
+                message, i, base.getClass().getSimpleName(),
+                packedInts.get(j).getClass().getSimpleName()),
+                base.get(i), packedInts.get(j).get(i));
+      }
+    }
+  }
+}
