Index: BitField.java
===================================================================
--- BitField.java	(revision 1665)
+++ BitField.java	(working copy)
@@ -86,7 +86,7 @@
      * @return the bit mask as a long
      */
     public long getLong(int i) {
-        int addr = getAddress(i);
+        int addr = i >> ADDRESS_BITS;
         if (addr >= data.length) {
             return 0;
         }
@@ -99,12 +99,12 @@
      * @param i the index
      * @return true if the bit is enabled
      */
-    public boolean get(int i) {
-        int addr = getAddress(i);
+    public boolean get(final int i) {
+        final int addr = i >> ADDRESS_BITS;
         if (addr >= data.length) {
             return false;
         }
-        return (data[addr] & getBitMask(i)) != 0;
+        return (data[addr] & (1L << (i & ADDRESS_MASK))) != 0;
     }
 
     /**
@@ -115,7 +115,7 @@
      * @return the next 8 bits
      */
     public int getByte(int i) {
-        int addr = getAddress(i);
+        int addr = i >> ADDRESS_BITS;
         if (addr >= data.length) {
             return 0;
         }
@@ -130,7 +130,7 @@
      * @param x the next 8 bits (0 - 255)
      */
     public void setByte(int i, int x) {
-        int addr = getAddress(i);
+        int addr = i >> ADDRESS_BITS;
         checkCapacity(addr);
         data[addr] |= ((long) x) << (i & (7 << 3));
     }
@@ -141,9 +141,9 @@
      * @param i the index
      */
     public void set(int i) {
-        int addr = getAddress(i);
+        int addr = i >> ADDRESS_BITS;
         checkCapacity(addr);
-        data[addr] |= getBitMask(i);
+        data[addr] |= 1L << (i & ADDRESS_MASK);
     }
 
     /**
@@ -152,18 +152,18 @@
      * @param i the index
      */
     public void clear(int i) {
-        int addr = getAddress(i);
+        int addr = i >> ADDRESS_BITS;
         if (addr >= data.length) {
             return;
         }
-        data[addr] &= ~getBitMask(i);
+        data[addr] &= ~(1L << (i & ADDRESS_MASK));
     }
 
-    private int getAddress(int i) {
+    private static int getAddress(int i) {
         return i >> ADDRESS_BITS;
     }
 
-    private long getBitMask(int i) {
+    private static long getBitMask(int i) {
         return 1L << (i & ADDRESS_MASK);
     }
 
@@ -185,24 +185,42 @@
     /**
      * Enable or disable a number of bits.
      *
+     * @author Samuel Van Oort
      * @param start the index of the first bit to enable or disable
      * @param len the number of bits to enable or disable
      * @param value the new value
      */
-    public void setRange(int start, int len, boolean value) {
-        // go backwards so that OutOfMemory happens
-        // before some bytes are modified
-        for (int i = start + len - 1; i >= start; i--) {
-            set(i, value);
+    public void setRange(final int start, final int len, final boolean value) {
+        final int startIdx = start >> ADDRESS_BITS;
+        final int endIdx = (start + len - 1) >> ADDRESS_BITS;
+        final int end = start+len;
+        
+        //Expand BitField if writing past end, unless clearing
+        //Prevents OutOfMemoryError mid-modify
+        final int datalen = data.length;
+        if (endIdx >= datalen) {
+            if (!value && startIdx >= datalen) {
+                return;
+            } 
+            expandCapacity(endIdx);
         }
-    }
-
-    private void set(int i, boolean value) {
+        long startMask = (~0L) << start;
+        long endMask = (~0L) >>> -end;
+        //If operating on one value, mask is combined
+        if (startIdx == endIdx) {
+            startMask &= endMask;
+            endMask = startMask; 
+        }
+        //Handle first & last longs
         if (value) {
-            set(i);
+            data[startIdx] |= startMask;
+            data[endIdx] |= endMask;
         } else {
-            clear(i);
+            data[startIdx] &= ~startMask;
+            data[endIdx] &= ~endMask;
         }
+        //Set full groups of longs very quickly to all 1 or all 0
+        final long setVal = value ? 0xFFFFFFFFFFFFFFFFL : 0;
+        java.util.Arrays.fill(data, startIdx + 1, endIdx, setVal);
     }
-
 }
