diff --git a/java/src/org/broadinstitute/sting/playground/utils/CircularArray.java b/java/src/org/broadinstitute/sting/playground/utils/CircularArray.java
new file mode 100644
index 000000000..28fc06074
--- /dev/null
+++ b/java/src/org/broadinstitute/sting/playground/utils/CircularArray.java
@@ -0,0 +1,206 @@
+package org.broadinstitute.sting.playground.utils;
+
+
+import org.broadinstitute.sting.utils.StingException;
+
+/** This class, closely resembling a deque (except that it is not dynamically grown),
+ * provides an object with array-like interface and efficient
+ * implementation of shift operation. Use this class when some kind of sliding window is required:
+ * e.g. an array (window) is populated from some stream of data, and then the window is shifted.
+ * If most of the data in the window remains the same so that only a few old elements sjould be popped from
+ * and a few new elements pushed onto the array, both re-populating the whole array from the data and
+ * shifting a regular array would be grossly inefficient. Instead, shiftData(int N) method of circular array
+ * efficiently pops out N first elements and makes last N elements available.
+ *
+ * Consider an example of reading a character stream A,B,C,D,....,Z into an array with requirement of keeping
+ * last 5 letters. First, we would read first 5 letters same way as we would with a regular array:
+ *
+ *
+ * CircularArray a(5);
+ * for ( int i = 0; i < 5; i++ ) a.set(i, readChar());
+ *
+ *
+ * and then on the arrival of each next character we shift the array:
+ *
+ *
+ * a.shiftData(1); a.set(4, readChar() );
+ *
+ *
+ * After the lines from the above example are executed, the array will logically look as:
+ *
+ * B,C,D,E,F,
+ *
+ * e.g. as if we had a regular array, shifted it one element down and added new element on the top.
+ *
+ *
+ * @author asivache
+ *
+ */
+public class CircularArray {
+
+
+ private Object[] data ;
+ private int offset;
+
+ /** Creates an array of fixed length */
+ public CircularArray(int length) {
+ if ( length <= 0 ) throw new StingException("CircularArray length must be positive. Passed: "+length);
+ data = new Object[length];
+ offset = 0;
+ }
+
+ /** Returns length of the array */
+ public int length() {
+ return data.length;
+ }
+
+ /** Gets i-th element of the array
+ *
+ * @throws IndexOutOfBoundsException if value of i is illegal
+ */
+ @SuppressWarnings("unchecked")
+ public T get(int i) {
+ if ( i < 0 || i >= data.length )
+ throw new IndexOutOfBoundsException("Length of CircularArray: "+data.length+"; element requested: "+i);
+ return (T)(data [ ( offset + i ) % data.length ]);
+ }
+
+ /** Sets i-th element of the array to the specified value.
+ *
+ * @throws IndexOutOfBoundsException if value of i is illegal
+ */
+ public void set(int i, T value) {
+ if ( i < 0 || i >= data.length )
+ throw new IndexOutOfBoundsException("Length of CircularArray: "+data.length+"; set element request at: "+i);
+ data [ ( offset + i ) % data.length ] = value;
+ }
+
+ /** Set all elements to null.
+ *
+ */
+ public void clear() {
+ for ( int i = 0 ; i < data.length ; i++ ) data[i] = null;
+ offset = 0;
+ }
+
+ /** Efficient shift-down of the array data. After this operation, array.get(0), array.get(1), etc will
+ * be returning what array.get(shift), array.get(shift+1),... were returning before the shift was performed,
+ * and last shift elements of the array will be reset to 0.
+ * @param shift
+ */
+ public void shiftData(int shift) {
+ if ( shift >= data.length ) {
+ // if we shift by more than the length of stored data, we lose
+ // all that data completely, so we just re-initialize the array.
+ // This is not the operating mode CircularArray is intended for
+ // but we can handle it, just in case.
+ for ( int i = 0 ; i < data.length ; i++ ) data[i] = null;
+ offset = 0;
+ return;
+ }
+
+ // shift < data.length, so at least some data should be preserved
+
+ final int newOffset = ( offset+shift ) % data.length;
+ if ( newOffset < offset ) {
+ // wrap-around!
+ for ( int i = offset ; i < data.length ; i++ ) data[i] = null;
+ for ( int i = 0; i < newOffset ; i++ ) data[i] = null;
+ } else {
+ for ( int i = offset ; i < newOffset ; i++ ) data[i] = null;
+ }
+ offset = newOffset;
+ }
+
+
+
+ /** Implements primitive int type-based circular array. See CircularArray for details.
+ *
+ * @author asivache
+ *
+ */
+ public static class Int {
+ private int [] data ;
+ private int offset;
+
+ /** Creates an array of fixed length */
+ public Int(int length) {
+ if ( length <= 0 ) throw new StingException("CircularArray length must be positive. Passed: "+length);
+ data = new int[length]; // automaticaly initialized to zeros
+ offset = 0;
+ }
+
+ /** Returns length of the array */
+ public int length() {
+ return data.length;
+ }
+
+ /** Gets i-th element of the array
+ *
+ * @throws IndexOutOfBoundsException if value of i is illegal
+ */
+ public int get(int i) {
+ if ( i < 0 || i >= data.length )
+ throw new IndexOutOfBoundsException("Length of CircularArray: "+data.length+"; element requested: "+i);
+ return data [ ( offset + i ) % data.length ];
+ }
+
+ /** Sets i-th element of the array to the specified value.
+ *
+ * @throws IndexOutOfBoundsException if value of i is illegal
+ */
+ public void set(int i, int value) {
+ if ( i < 0 || i >= data.length )
+ throw new IndexOutOfBoundsException("Length of CircularArray: "+data.length+"; set element request at: "+i);
+ data [ ( offset + i ) % data.length ] = value;
+ }
+
+ /** Increments i-th element of the array by the specified value (value can be negative).
+ *
+ * @throws IndexOutOfBoundsException if i is illegal
+ */
+ public void increment(int i, int value) {
+ if ( i < 0 || i >= data.length )
+ throw new IndexOutOfBoundsException("Length of CircularArray: "+data.length+"; increment element request at: "+i);
+ data [ ( offset + i ) % data.length ] += value;
+ }
+
+ /** Set all elements to 0.
+ *
+ */
+ public void clear() {
+ for ( int i = 0 ; i < data.length ; i++ ) data[i] = 0;
+ offset = 0;
+ }
+
+ /** Efficient shift-down of the array data. After this operation, array.get(0), array.get(1), etc will
+ * be returning what array.get(shift), array.get(shift+1),... were returning before the shift was performed,
+ * and last shift elements of the array will be reset to 0.
+ * @param shift
+ */
+ public void shiftData(int shift) {
+ if ( shift >= data.length ) {
+ // if we shift by more than the length of stored data, we lose
+ // all that data completely, so we just re-initialize the array.
+ // This is not the operating mode CircularArray is intended for
+ // but we can handle it, just in case.
+ for ( int i = 0 ; i < data.length ; i++ ) data[i] = 0;
+ offset = 0;
+ return;
+ }
+
+ // shift < data.length, so at least some data should be preserved
+
+ final int newOffset = ( offset+shift ) % data.length;
+ if ( newOffset < offset ) {
+ // wrap-around!
+ for ( int i = offset ; i < data.length ; i++ ) data[i] = 0;
+ for ( int i = 0; i < newOffset ; i++ ) data[i] = 0;
+ } else {
+ for ( int i = offset ; i < newOffset ; i++ ) data[i] = 0;
+ }
+ offset = newOffset;
+ }
+ }
+
+}