Index: src/test/org/apache/lucene/util/TestPackedInts.java
===================================================================
--- src/test/org/apache/lucene/util/TestPackedInts.java	(revision 0)
+++ src/test/org/apache/lucene/util/TestPackedInts.java	(revision 0)
@@ -0,0 +1,70 @@
+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 org.apache.lucene.store.*;
+
+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 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, ceil-1, valueCount,
+                PackedInts.PRIORITY.packed, PackedInts.BLOCK_PREFERENCE.bit64);
+
+        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("i=" + i + " ceil=" + ceil, values[i], r.get(i));
+        }
+        in.close();
+        ceil *= 2;
+      }
+    }
+  }
+}
Index: src/java/org/apache/lucene/store/IndexInput.java
===================================================================
--- src/java/org/apache/lucene/store/IndexInput.java	(revision 902066)
+++ src/java/org/apache/lucene/store/IndexInput.java	(working copy)
@@ -64,6 +64,13 @@
     readBytes(b, offset, len);
   }
 
+  /** Reads two bytes and returns a short.
+   * @see IndexOutput#writeInt(int)
+   */
+  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/Packed64.java
===================================================================
--- src/java/org/apache/lucene/util/Packed64.java	(revision 0)
+++ src/java/org/apache/lucene/util/Packed64.java	(revision 0)
@@ -0,0 +1,225 @@
+package org.apache.lucene.util;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+
+import java.io.IOException;
+
+/**
+ * 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.
+ */
+public class Packed64 implements PackedInts.Reader {
+  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 number of bits representing an element */
+  private int elementBits;
+  /* The number of blocks. */
+  private int size;
+  /* The bits */
+  private long[] blocks;
+
+  // Cached calculations
+  private long maxValue;    // Math.pow(elementBits, 2)-1
+  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 maxValue the maximum value for an element.
+   */
+  public Packed64(int valueCount, long maxValue) {
+    int bits = PackedInts.bitsRequired(maxValue);
+    // +2 due to the avoid-conditionals-trick. The last entry is always 0
+    setAttributes(bits, 0, new long[valueCount * bits / BLOCK_SIZE + 2]);
+  }
+
+
+  /**
+   * 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 maxValue the maximum value for any given element.
+   */
+  public Packed64(long[] blocks, long maxValue) {
+    int bits = PackedInts.bitsRequired(maxValue);
+    setAttributes(bits, 0, blocks);
+  }
+
+  /**
+   * 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 maxValue the maximum value for an element.
+   * @throws java.io.IOException if the values for the backing array could not
+   *                             be retrieved.
+   */
+  public Packed64(IndexInput in, int valueCount, long maxValue)
+                                                            throws IOException {
+    int bits = PackedInts.bitsRequired(maxValue);
+    int size = size(bits, valueCount);
+    long[] blocks = new long[size+1]; // +1 due to non-conditional tricks
+    for(int i=0;i<size;i++) {
+      blocks[i] = in.readLong();
+    }
+    setAttributes(bits, valueCount, blocks);
+  }
+
+  private static int size(int bitsPerValue, int valueCount) {
+    final long totBitCount = (long) valueCount * bitsPerValue;
+    return (int) (totBitCount/64 + ((totBitCount % 64 == 0 ) ? 0:1));
+  }
+
+  private void setAttributes(int elementBits, int size, long[] blocks) {
+    this.elementBits = elementBits;
+    this.size = size;
+    this.blocks = blocks;
+    updateCached();
+  }
+
+  private void updateCached() {
+    readMasks = MASKS[elementBits];
+    maxValue = elementBits == 63 ? Long.MAX_VALUE :
+            (long)Math.pow(2, elementBits)-1;
+    maxPos = (blocks.length * BLOCK_SIZE / elementBits) - 2;
+    shifts = SHIFTS[elementBits];
+    writeMasks = WRITE_MASKS[elementBits];
+  }
+
+  /**
+   * @param index the position of the value.
+   * @return the value at the given index.
+   */
+  public long get(final int index) {
+    final long majorBitPos = index * elementBits;
+    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 * elementBits;
+    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(elementBits=" + elementBits + ", size="
+            + size + ", maxPos=" + maxPos
+            + ", elements.length=" + blocks.length + ")";
+  }
+
+  public long getMaxValue() {
+    return maxValue;
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER
+            + blocks.length * RamUsageEstimator.NUM_BYTES_LONG;
+  }
+
+  public static PackedInts.Writer getWriter(
+          IndexOutput out, long maxValue, int valueCount) throws IOException {
+    return new PackedWriter(out, maxValue, valueCount,
+            PackedInts.bitsRequired(maxValue));
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/PackedDirectLong.java
===================================================================
--- src/java/org/apache/lucene/util/PackedDirectLong.java	(revision 0)
+++ src/java/org/apache/lucene/util/PackedDirectLong.java	(revision 0)
@@ -0,0 +1,80 @@
+package org.apache.lucene.util;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+
+import java.io.IOException;
+
+/**
+ * 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.
+ */
+public class PackedDirectLong implements PackedInts.Reader {
+  private long[] blocks;
+
+  public PackedDirectLong(int length, long maxValue) {
+    blocks = new long[length];
+  }
+
+  public PackedDirectLong(IndexInput in, int valueCount, long maxValue)
+          throws IOException {
+    System.out.println("r");
+    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.
+   * @param maxValue the maximum value for any given element.
+   */
+  public PackedDirectLong(long[] blocks, long maxValue) {
+    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 getMaxValue() {
+    return Long.MAX_VALUE;
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER +
+            blocks.length * RamUsageEstimator.NUM_BYTES_LONG;
+  }
+
+  public static PackedInts.Writer getWriter(
+          IndexOutput out, long maxValue, int valueCount) throws IOException {
+    return new PackedWriter(out, Long.MAX_VALUE, valueCount, 63);
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/PackedDirectByte.java
===================================================================
--- src/java/org/apache/lucene/util/PackedDirectByte.java	(revision 0)
+++ src/java/org/apache/lucene/util/PackedDirectByte.java	(revision 0)
@@ -0,0 +1,99 @@
+package org.apache.lucene.util;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+
+import java.io.IOException;
+
+/**
+ * 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.
+ */
+public class PackedDirectByte implements PackedInts.Reader {
+  private byte[] blocks;
+
+  public PackedDirectByte(int length, long maxValue) {
+    checkBits(maxValue);
+    blocks = new byte[length];
+  }
+
+  public PackedDirectByte(IndexInput in, int valueCount, long maxValue)
+          throws IOException {
+    checkBits(maxValue);
+    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;
+  }
+
+  private void checkBits(long maxValue) {
+    int bits = PackedInts.bitsRequired(maxValue);
+    if (bits > 8) {
+      throw new IllegalArgumentException(String.format(
+              "This array only supports values of 8 bits or less. The "
+                      + "required number of bits was %d.",
+              bits));
+    }
+  }
+
+
+  /**
+   * 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.
+   * @param maxValue the maximum value for any given element.
+   */
+  public PackedDirectByte(byte[] blocks, long maxValue) {
+    checkBits(maxValue);
+    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 getMaxValue() {
+    return 255;
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER + blocks.length;
+  }
+
+  public static PackedInts.Writer getWriter(
+          IndexOutput out, long maxValue, int valueCount) throws IOException {
+    return new PackedWriter(out, 255, valueCount, 8);
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/CodecUtil.java
===================================================================
--- src/java/org/apache/lucene/util/CodecUtil.java	(revision 0)
+++ src/java/org/apache/lucene/util/CodecUtil.java	(revision 0)
@@ -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/PackedWriter.java
===================================================================
--- src/java/org/apache/lucene/util/PackedWriter.java	(revision 0)
+++ src/java/org/apache/lucene/util/PackedWriter.java	(revision 0)
@@ -0,0 +1,102 @@
+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 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.
+ */
+public class PackedWriter extends PackedInts.Writer {
+  private long pending;
+  private int pendingBitPos;
+
+  // masks[n-1] masks for bottom n bits
+  private final long[] masks;
+
+  // nocommit -- allow minValue too?  ie not just minValue==0
+
+  public PackedWriter(IndexOutput out, long maxValue, int valueCount,
+                      int bitsPerValue) throws IOException {
+
+    super(out, maxValue, 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
+   */
+  public void add(long v) throws IOException {
+    assert v <= maxValue : "v=" + v + " maxValue=" + maxValue;
+    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);
+    }
+  }
+
+  public void finish() throws IOException {
+    if (pendingBitPos != 64) {
+      out.writeLong(pending);
+    }
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/PackedInts.java
===================================================================
--- src/java/org/apache/lucene/util/PackedInts.java	(revision 0)
+++ src/java/org/apache/lucene/util/PackedInts.java	(revision 0)
@@ -0,0 +1,330 @@
+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.
+ */
+
+// nocommit -- rename to UnsignedPackedInts?  or pull
+// minValue down
+
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.store.IndexInput;
+
+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.
+ *
+ * <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!
+ */
+
+// nocommit
+//   - do we need int/long variants (for perf)?  or long
+//     only suffices?
+//   - what native type is best perf?  long/int/short/byte?
+
+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>
+   * space:   Pack the bits right after each other.<br />
+   * aligned: Pack bits so that no values cross block boundaries.<br />
+   * direct:  Store bits directly as byte, short, integer or long array.
+   * </p><p>
+   * Note: When a more efficient structure (in terms of memory as well as speed)
+   * can be substituted without penalty, this will be done. Example:
+   * Asking for packed with 3 bits/value will return packed32 or packed64, while
+   * asking for packed with 4 bits/value will return aligned32 or aligned64.
+   * Asking for aligned with 7 bits/value and block preferences bit32 will
+   * return directByte, as this amount of space used by an aligned32 with 7
+   * bits/value is the same as directByte, while directByte is less processor-
+   * intensive.
+   * </p><p>
+   * Note: Selecting direct does not guarantee the best speed, as using direct
+   * for setups such as 9 bits/value nearly doubles the size of the backing
+   * array and makes level 2 cache misses more likely.
+   * </p><p>
+   * Note: 63 bits/value will always be mapped to a directLong, due to the
+   *       problem of stating maxValues > 2^63-1.
+   */
+  public enum PRIORITY {packed, aligned, direct}
+  // Consider making a "smart"-option. 31, 63 and probably 62, 61 or 60
+  // bis/value should normally be represented by a direct, as the space-loss
+  // is minimal and the speed-gain is significant.
+
+  /**
+   * The preference for the underlying blocks for packed or aligned structures.
+   * Using 64bit blocks (longs) on a 32bit machine is slower than using 32bit
+   * blocks (ints).
+   */
+  public enum BLOCK_PREFERENCE {bit32, bit64}
+
+  /**
+   * The specific implementation derived from bits/value, PRIORITY and
+   * BLOCK_PREFERENCE.
+   */
+  enum IMPLEMENTATION {packed32, packed64, aligned32, aligned64,
+    directByte, directShort, directInt, directLong}
+
+  /**
+   *
+   */
+  enum PERSISTENCE {packed, aligned32, aligned64}
+
+  /**
+   * Derives the optimal IMPLEMENTATION based on the given preferences.
+   * @param maxValue  the maximum value that the structure can hold.
+   * @param priority  memory/speed trade-off.
+   * @param block     the expected architecture for the system that will
+   *                use the Reader-part of the structure.
+   * @return the implementation to use.
+   */
+  private static IMPLEMENTATION getImplementation(
+          long maxValue, PRIORITY priority, BLOCK_PREFERENCE block) {
+    int bits = bitsRequired(maxValue);
+    switch (priority) {
+      case direct: {
+        bits = getNextFixedSize(bits);
+        break;
+      }
+      case aligned: {
+        if (block == BLOCK_PREFERENCE.bit32) {
+          if (bits == 7 || bits >= 11) {
+            bits = getNextFixedSize(bits); // Align to byte, short, int or long
+          }
+        } else {
+          if ((bits >= 13 && bits <= 15) || (bits >= 22)) {
+            bits = getNextFixedSize(bits); // Align to short, int or long
+          }
+        }
+      }
+    }
+    switch (bits) { // The safe choices
+      case 8: return IMPLEMENTATION.directByte;
+      case 16: return IMPLEMENTATION.directShort;
+      case 32: return IMPLEMENTATION.directInt;
+      case 63:
+      case 64: return IMPLEMENTATION.directLong;
+    }
+
+    // Not implemented yet
+/*
+    if (priority == PRIORITY.aligned || bits == 1 || bits == 2 || bits == 4) {
+      return block == BLOCK_PREFERENCE.bit32 && bits < 32 ?
+              IMPLEMENTATION.aligned32 : IMPLEMENTATION.aligned64;
+    }
+    return block == BLOCK_PREFERENCE.bit32 && bits < 32 ?
+            IMPLEMENTATION.packed32 : IMPLEMENTATION.packed64;
+            */
+
+    return IMPLEMENTATION.packed64;
+  }
+
+  /**
+   * Derives the optimal IMPLEMENTATION based on the given preferences.
+   * Used for creating arrays from persistent data.
+   * @param persistence the format of the existing data.
+   * @param maxValue  the maximum value that the structure can hold.
+   * @param block     the expected architecture for the system that will
+   *                  use the Reader-part of the structure.
+   * @return the implementation to use.
+   */
+  private static IMPLEMENTATION getImplementation(PERSISTENCE persistence,
+                                                  long maxValue, BLOCK_PREFERENCE block) {
+    int bits = bitsRequired(maxValue);
+    switch (bits) { // The safe choices
+      case 8: return IMPLEMENTATION.directByte;
+      case 16: return IMPLEMENTATION.directShort;
+      case 32: return IMPLEMENTATION.directInt;
+      case 63:
+      case 64: return IMPLEMENTATION.directLong;
+    }
+    return IMPLEMENTATION.packed64;
+  }
+
+  private static int size(int bitsPerValue, int valueCount) {
+    final long totBitCount = (long) valueCount * bitsPerValue;
+    return (int) (totBitCount/64 + ((totBitCount % 64 == 0 ) ? 0:1));
+  }
+
+  /** Returns how many bits are required to hold values up
+   *  to and including maxValue */
+  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));
+  }
+
+  public 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;
+    }
+  }
+
+  /** Write-once */
+  public static abstract class Writer {
+    protected final IndexOutput out;
+    protected final int bitsPerValue;
+    protected final long maxValue;
+    protected final int valueCount;
+
+    protected Writer(IndexOutput out, long maxValue, int valueCount,
+                     int bitsPerValue, PERSISTENCE persistence)
+            throws IOException {
+      assert bitsPerValue <= 64;
+
+
+      this.out = out;
+      this.maxValue = maxValue;
+      this.valueCount = valueCount;
+      this.bitsPerValue = bitsPerValue;
+
+      CodecUtil.writeHeader(out, CODEC_NAME, VERSION_START);
+      out.writeString(persistence.toString());
+//      out.writeVInt(bitsPerValue); // Why use both this and maxValue?
+      // The problem with bitsPerValue is that it is implementation-specific,
+      // while maxValue is general
+
+      out.writeVInt(valueCount);
+      out.writeVLong(maxValue);
+    }
+
+    public abstract void add(long v) throws IOException;
+    public abstract void finish() throws IOException;
+  }
+
+  public static Writer getWriter(
+          IndexOutput out, long maxValue, int valueCount,
+          PRIORITY priority, BLOCK_PREFERENCE block) throws IOException {
+    IMPLEMENTATION implementation = getImplementation(
+            maxValue, priority, block);
+    switch (implementation) {
+      case packed64:
+        return Packed64.getWriter(out, maxValue, valueCount);
+      case directByte:
+        return PackedDirectByte.getWriter(out, maxValue, valueCount);
+      case directShort:
+        return PackedDirectShort.getWriter(out, maxValue, valueCount);
+      case directInt:
+        return PackedDirectInt.getWriter(out, maxValue, valueCount);
+      case directLong:
+        return PackedDirectLong.getWriter(out, maxValue, valueCount);
+      default: throw new UnsupportedOperationException(
+              implementation + " not implemented yet");
+    }
+/*    final int bitsPerValue;
+    if (forceBits != -1) {
+      bitsPerValue = forceBits;
+    } else {
+      if (maxValue == 0) {
+        maxValue = 1;
+      }
+      bitsPerValue = bitsRequired(maxValue);
+    }
+    assert bitsPerValue <= 64;
+    return new PackedWriter64(out, maxValue, valueCount, bitsPerValue);*/
+  }
+
+  public static abstract interface Reader extends ConsumesRAM {
+    long get(int index);
+    long getMaxValue();
+  }
+
+  public static abstract class ReaderImpl implements Reader {
+    private final long maxValue;
+
+    protected ReaderImpl(long maxValue) {
+      this.maxValue = maxValue;
+    }
+
+    public long getMaxValue() {
+      return maxValue;
+    }
+  }
+
+  public static Reader getReader(IndexInput in) throws IOException {
+    return getReader(in, Constants.JRE_IS_64BIT ?
+            BLOCK_PREFERENCE.bit64 : BLOCK_PREFERENCE.bit64);
+  }
+  public static Reader getReader(IndexInput in, BLOCK_PREFERENCE block)
+          throws IOException {
+    CodecUtil.checkHeader(in, CODEC_NAME, VERSION_START);
+//    final int bitsPerValue = in.readVInt();
+    String pStr = in.readString();
+    PERSISTENCE persistence = PERSISTENCE.valueOf(pStr);
+    final int valueCount = in.readVInt();
+    final long maxValue = in.readVLong();
+
+    IMPLEMENTATION implementation =
+            getImplementation(persistence, maxValue, block);
+    switch (implementation) {
+      case packed64: return new Packed64(in, valueCount, maxValue);
+      case directByte: return new PackedDirectByte(in, valueCount, maxValue);
+      case directShort: return new PackedDirectShort(in, valueCount, maxValue);
+      case directInt: return new PackedDirectInt(in, valueCount, maxValue);
+      case directLong: return new PackedDirectLong(in, valueCount, maxValue);
+      default: throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    // TODO an mmap reader as well?
+
+    /*
+    // dedicated fixed array based readers for bit sizes matching java native types
+    switch(bitsPerValue) {
+    case 8:
+      return new ByteReader(in, valueCount, maxValue);
+    case 16:
+      return new ShortReader(in, valueCount, maxValue);
+    case 32:
+      return new IntReader(in, valueCount, maxValue);
+    case 64:
+      return new LongReader(in, valueCount, maxValue);
+    }
+
+    // else, read all data into long[] and instantiate
+    // dedicated bit packed reader
+    final int size = size(bitsPerValue, valueCount);
+    final long[] data = new long[size+1]; // +1 to compensate for non-conditional tricks in Packed32/64
+    // TODO: switch to ByteBuffer
+    for(int i=0;i<size;i++) {
+      data[i] = in.readLong();
+    }
+*/
+  }
+}
Index: src/java/org/apache/lucene/util/PackedDirectInt.java
===================================================================
--- src/java/org/apache/lucene/util/PackedDirectInt.java	(revision 0)
+++ src/java/org/apache/lucene/util/PackedDirectInt.java	(revision 0)
@@ -0,0 +1,96 @@
+package org.apache.lucene.util;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+
+import java.io.IOException;
+
+/**
+ * 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.
+ */
+public class PackedDirectInt implements PackedInts.Reader {
+  private int[] blocks;
+
+  public PackedDirectInt(int length, long maxValue) {
+    checkBits(maxValue);
+    blocks = new int[length];
+  }
+
+  public PackedDirectInt(IndexInput in, int valueCount, long maxValue)
+          throws IOException {
+    checkBits(maxValue);
+    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;
+  }
+
+  private void checkBits(long maxValue) {
+    int bits = PackedInts.bitsRequired(maxValue);
+    if (bits > 32) {
+      throw new IllegalArgumentException(String.format(
+              "This array only supports values of 32 bits or less. The "
+                      + "required number of bits was %d.",
+              bits));
+    }
+  }
+
+
+  /**
+   * 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.
+   * @param maxValue the maximum value for any given element.
+   */
+  public PackedDirectInt(int[] blocks, long maxValue) {
+    checkBits(maxValue);
+    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 getMaxValue() {
+    return 256L*256*256*256-1;
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER +
+            blocks.length * RamUsageEstimator.NUM_BYTES_INT;
+  }
+
+  public static PackedInts.Writer getWriter(
+          IndexOutput out, long maxValue, int valueCount) throws IOException {
+    return new PackedWriter(out, 256L*256*256*256-1, valueCount, 32);
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/PackedDirectShort.java
===================================================================
--- src/java/org/apache/lucene/util/PackedDirectShort.java	(revision 0)
+++ src/java/org/apache/lucene/util/PackedDirectShort.java	(revision 0)
@@ -0,0 +1,100 @@
+package org.apache.lucene.util;
+
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+
+import java.io.IOException;
+
+/**
+ * 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.
+ */
+public class PackedDirectShort implements PackedInts.Reader {
+  private short[] blocks;
+
+  public PackedDirectShort(int length, long maxValue) {
+    checkBits(maxValue);
+    blocks = new short[length];
+  }
+
+  public PackedDirectShort(IndexInput in, int valueCount, long maxValue)
+          throws IOException {
+    checkBits(maxValue);
+    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;
+  }
+
+  private void checkBits(long maxValue) {
+    int bits = PackedInts.bitsRequired(maxValue);
+    if (bits > 16) {
+      throw new IllegalArgumentException(String.format(
+              "This array only supports values of 16 bits or less. The "
+                      + "required number of bits was %d.",
+              bits));
+    }
+  }
+
+
+  /**
+   * 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.
+   * @param maxValue the maximum value for any given element.
+   */
+  public PackedDirectShort(short[] blocks, long maxValue) {
+    checkBits(maxValue);
+    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 getMaxValue() {
+    return 256*256-1;
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER +
+            blocks.length * RamUsageEstimator.NUM_BYTES_SHORT;
+  }
+
+  public static PackedInts.Writer getWriter(
+          IndexOutput out, long maxValue, int valueCount) throws IOException {
+    return new PackedWriter(out, 256*256-1, valueCount, 16);
+  }
+}
\ No newline at end of file
Index: src/java/org/apache/lucene/util/GenBitReaders.java
===================================================================
--- src/java/org/apache/lucene/util/GenBitReaders.java	(revision 0)
+++ src/java/org/apache/lucene/util/GenBitReaders.java	(revision 0)
@@ -0,0 +1,6305 @@
+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.
+ */
+
+// Autogenerated by gen.py DO NOT EDIT!
+class GenBitReaders {
+  static abstract class Base extends PackedInts.ReaderImpl {
+    protected final long[] data;
+    protected Base(long[] data, long maxValue) {
+      super(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/gen.py
===================================================================
--- src/java/org/apache/lucene/util/gen.py	(revision 0)
+++ src/java/org/apache/lucene/util/gen.py	(revision 0)
@@ -0,0 +1,116 @@
+import sys
+
+# usage: python gen.py > src/java/org/apache/lucene/util/GenBitReaders.java
+
+def gen():
+
+  print 'package org.apache.lucene.util;'
+
+  print '''
+/**
+ * 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.
+ */
+'''
+  print '// Autogenerated by gen.py DO NOT EDIT!'
+
+  print 'class GenBitReaders {'
+  print '  static abstract class Base extends PackedInts.Reader {'
+  print '    protected final long[] data;'
+  print '    protected Base(long[] data, long maxValue) {'
+  print '      super(maxValue);'
+  print '      this.data = data;'
+  print '    }'
+  print '    public long ramBytesUsed() {'
+  print '      return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER + data.length * RamUsageEstimator.NUM_BYTES_LONG;'
+  print '    }'
+  print '  }'
+  print
+
+  for nbits in range(1, 65):
+
+    if nbits in (8, 16, 32, 64):
+      # we have dedicated array readers for these cases
+      continue
+    
+    print '  final static class Reader%d extends Base {' % nbits
+    print '    public Reader%d(long[] data, long maxValue) {' % nbits
+    print '      super(data, maxValue);'
+    print '    }'
+    
+    print '    public long get(int pos) {'
+
+    print '      final long bit = pos*%s;' % nbits
+    print '      final int idx = (int) (bit>>6);'
+    print '      switch((int) (bit & 63)) {'
+
+    masks = []
+    v = 2
+    for j in range(nbits):
+      masks.append(v-1)
+      v *= 2
+
+    mask = (1<<nbits)-1;
+
+    d = set()
+    bit = 0
+    # enumerate all possible alignments
+    while True:
+      if bit in d:
+        break
+      d.add(bit)
+
+      print '      case %d:' % bit
+
+      # we pack high order bytes first
+      bitStart = 64 - bit
+
+      if bitStart >= nbits:
+        # not split
+        if bitStart == nbits:
+          # no shift needed, mask needed
+          print '        return data[idx] & %sL;' % mask
+        elif bitStart == 64:
+          # shift, but not mask, needed
+          print '        return data[idx] >>> %s;' % (bitStart-nbits)
+        else:
+          # shift & mask needed
+          print '        return (data[idx] >>> %s) & %sL;' % (bitStart-nbits, mask)
+      else:
+        # split
+        print '        return ((data[idx] & %sL) << %s) | (data[1+idx] >>> %d);' % \
+              (masks[bitStart-1], nbits-bitStart, 64-(nbits-bitStart))
+      bit = (bit + nbits) % 64
+      
+    print '      }'
+    print
+    print '      // unreachable, but compiler disagrees'
+    print '      return 0;'
+    print '    }'
+    print '  }'
+
+  print '}'
+
+  if False:
+    print
+    print
+    print
+    print '    switch(bitsPerValue) {'
+    for i in range(1, 65):
+      print '    case %d:' % i
+      print '      return new PackedBitReaders.Reader%d(data, maxValue);' % i
+    print '    }'
+
+gen()
Index: src/java/org/apache/lucene/util/BytesRef.java
===================================================================
--- src/java/org/apache/lucene/util/BytesRef.java	(revision 0)
+++ src/java/org/apache/lucene/util/BytesRef.java	(revision 0)
@@ -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/Packed32.java
===================================================================
--- src/java/org/apache/lucene/util/Packed32.java	(revision 0)
+++ src/java/org/apache/lucene/util/Packed32.java	(revision 0)
@@ -0,0 +1,197 @@
+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.
+ */
+
+/**
+ * Space optimized random access capable array of values with a fixed number of
+ * bits. The maximum number of bits/value is 32. Use {@link Packed64} for higher
+ * numbers.
+ * </p><p>
+ * The implementation strives to avoid conditionals and expensive operations,
+ * sacrificing code clarity to achieve better performance.
+ */
+public class Packed32 implements PackedInts.Reader {
+  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 number of bits representing an element */
+  private int elementBits;
+  /* The number of blocks. */
+  private int size;
+  /* The bits */
+  private int[] blocks;
+
+  // Cached calculations
+  private int maxValue;    // Math.pow(elementBits, 2)-1
+  private int maxPos;      // blocks.length * BLOCK_SIZE / elementBits - 1
+  private int[] shifts;    // The shifts for the current elementBits
+  private int[] readMasks;
+  private int[] writeMasks;
+
+  /**
+   * Creates an array with the internal structures adjusted for the given
+   * limits and initialized to 0.
+   * @param length   the number of elements.
+   * @param maxValue the maximum value for an element.
+   */
+  public Packed32(int length, long maxValue) {
+    int bits = PackedInts.bitsRequired(maxValue);
+    if (bits > 32) {
+      throw new IllegalArgumentException(String.format(
+              "This array only supports values of 32 bits or less. The "
+                      + "required number of bits was %d. The Packed64 "
+                      + "implementation allows values with more than 32 bits",
+              bits));
+    }
+    setAttributes(bits, 0, new int[length * bits / BLOCK_SIZE + 2]);
+  }
+
+
+  /**
+   * 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 maxValue the maximum value for any given element.
+   */
+  public Packed32(int[] blocks, long maxValue) {
+    int bits = PackedInts.bitsRequired(maxValue);
+    setAttributes(bits, 0, blocks);
+  }
+
+  private void setAttributes(int elementBits, int size, int[] blocks) {
+    this.elementBits = elementBits;
+    this.size = size;
+    this.blocks = blocks;
+    updateCached();
+  }
+
+  private void updateCached() {
+    readMasks = MASKS[elementBits];
+    maxValue = (int)Math.pow(2, elementBits)-1;
+    maxPos = (blocks.length * BLOCK_SIZE / elementBits) - 2;
+    shifts = SHIFTS[elementBits];
+    writeMasks = WRITE_MASKS[elementBits];
+  }
+
+  /**
+   * @param index the position of the value.
+   * @return the value at the given index.
+   */
+  public long get(final int index) {
+    final long majorBitPos = index * elementBits;
+    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]);
+  }
+
+  // TODO: Check behaviour at 32 bits/value
+  public void set(final int index, final long value) {
+    final int intValue = (int)value;
+    final long majorBitPos = index * elementBits;
+    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 String toString() {
+    return "Packed32(elementBits=" + elementBits + ", size="
+            + size + ", maxPos=" + maxPos
+            + ", elements.length=" + blocks.length + ")";
+  }
+
+  public long getMaxValue() {
+    return maxValue;
+  }
+
+  public long ramBytesUsed() {
+    return RamUsageEstimator.NUM_BYTES_ARRAY_HEADER
+            + blocks.length * RamUsageEstimator.NUM_BYTES_INT;
+  }
+}
Index: src/java/org/apache/lucene/util/ConsumesRAM.java
===================================================================
--- src/java/org/apache/lucene/util/ConsumesRAM.java	(revision 0)
+++ src/java/org/apache/lucene/util/ConsumesRAM.java	(revision 0)
@@ -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/RamUsageEstimator.java
===================================================================
--- src/java/org/apache/lucene/util/RamUsageEstimator.java	(revision 902066)
+++ src/java/org/apache/lucene/util/RamUsageEstimator.java	(working copy)
@@ -35,6 +35,16 @@
  * estimate is complete.
  */
 public final class RamUsageEstimator {
+
+  public static int NUM_BYTES_SHORT = 2;
+  public static int NUM_BYTES_INT = 4;
+  public static int NUM_BYTES_LONG = 8;
+  public static int NUM_BYTES_FLOAT = 4;
+  public static int NUM_BYTES_DOUBLE = 8;
+  public static int NUM_BYTES_OBJ_HEADER = 8;
+  public static int NUM_BYTES_OBJ_REF = Constants.JRE_IS_64BIT ? 8 : 4;
+  public 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;
 
