// Path: orderly-core/src/main/java/orderly/Order.java
// public enum Order
// { 
//   ASCENDING((byte)0), 
//   DESCENDING((byte)0xff);
// 
//   private final byte mask;
// 
//   Order(byte mask) { this.mask = mask; }
// 
//   /** Gets the byte mask associated with the sort order. When a 
//    * serialized byte is XOR'd with the mask, the result is the same byte 
//    * but sorted in the direction specified by the Order object. 
//    * @see RowKey#serialize
//    */
//   byte mask() { return mask; }
// 
// }
// 
// Path: orderly-core/src/main/java/orderly/RowKeyUtils.java
// public class RowKeyUtils 
// {
//   /** Shared (immutable) zero-length byte array singleton. */
//   public static final byte[] EMPTY = new byte[0];
// 
//   /** Converts a (byte array, offset, length) triple into a byte array,
//    * copying only if necessary. No copy is performed if offset is 0 and
//    * length is array.length. 
//    */
//   public static byte[] toBytes(byte[] b, int offset, int length) {
//     if (offset == 0 && length == b.length) 
//       return b;
//     else if (offset == 0)
//       return Arrays.copyOf(b, length);
//     return Arrays.copyOfRange(b, offset, offset + length);
//   }
// 
//   /** Converts an ImmutableBytesWritable to a byte array, copying only if
//    * necessary.
//    */
//   public static byte[] toBytes(ImmutableBytesWritable w) {
//     return toBytes(w.get(), w.getOffset(), w.getLength());
//   }
// 
//   /** Converts a Text object to a byte array, copying only if
//    * necessary.
//    */
//   public static byte[] toBytes(Text t) {
//     return toBytes(t.getBytes(), 0, t.getLength());
//   }
// 
//   /** Seeks forward/backward within an ImmutableBytesWritable. After
//    * seek is complete, the position (length) of the byte array is 
//    * incremented (decremented) by the seek amount.
//    * @param w  immutable byte array used for seek
//    * @param offset number of bytes to seek (relative to current position)
//    */
//   public static void seek(ImmutableBytesWritable w, int offset) {
//     w.set(w.get(), w.getOffset() + offset, w.getLength() - offset);
//   }
// }
// 
// Path: orderly-core/src/main/java/orderly/Termination.java
// public enum Termination {
//     AUTO, MUST, SHOULD_NOT
// }


import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import orderly.Order;
import orderly.RowKeyUtils;
import orderly.Termination;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.junit.Before;
import org.junit.Test;
  public RandomRowKeyTestCase setNumTests(int numTests) {
    this.numTests = numTests;
    return this;
  }

  public RandomRowKeyTestCase setMaxRedZone(int maxRedZone) {
    this.maxRedZone = maxRedZone;
    return this;
  }

  @Override
  public ImmutableBytesWritable allocateBuffer(Object o) throws IOException {
    return new RedZoneImmutableBytesWritable(key.getSerializedLength(o),
        key.getTermination() == Termination.MUST);
  }

  @Override
  public void serialize(Object o, ImmutableBytesWritable w) throws IOException
  {
    byte[] b;
    int len;

    switch(r.nextInt(4)) {
      case 0: /* serialize(Object, ImmutableBytesWritable) */
        key.serialize(o, w);
        break;

      case 1: /* serialize(Object) */
        b = key.serialize(o);
        System.arraycopy(b, 0, w.get(), w.getOffset(), b.length);
// Path: orderly-core/src/main/java/orderly/Order.java
// public enum Order
// { 
//   ASCENDING((byte)0), 
//   DESCENDING((byte)0xff);
// 
//   private final byte mask;
// 
//   Order(byte mask) { this.mask = mask; }
// 
//   /** Gets the byte mask associated with the sort order. When a 
//    * serialized byte is XOR'd with the mask, the result is the same byte 
//    * but sorted in the direction specified by the Order object. 
//    * @see RowKey#serialize
//    */
//   byte mask() { return mask; }
// 
// }
// 
// Path: orderly-core/src/main/java/orderly/RowKeyUtils.java
// public class RowKeyUtils 
// {
//   /** Shared (immutable) zero-length byte array singleton. */
//   public static final byte[] EMPTY = new byte[0];
// 
//   /** Converts a (byte array, offset, length) triple into a byte array,
//    * copying only if necessary. No copy is performed if offset is 0 and
//    * length is array.length. 
//    */
//   public static byte[] toBytes(byte[] b, int offset, int length) {
//     if (offset == 0 && length == b.length) 
//       return b;
//     else if (offset == 0)
//       return Arrays.copyOf(b, length);
//     return Arrays.copyOfRange(b, offset, offset + length);
//   }
// 
//   /** Converts an ImmutableBytesWritable to a byte array, copying only if
//    * necessary.
//    */
//   public static byte[] toBytes(ImmutableBytesWritable w) {
//     return toBytes(w.get(), w.getOffset(), w.getLength());
//   }
// 
//   /** Converts a Text object to a byte array, copying only if
//    * necessary.
//    */
//   public static byte[] toBytes(Text t) {
//     return toBytes(t.getBytes(), 0, t.getLength());
//   }
// 
//   /** Seeks forward/backward within an ImmutableBytesWritable. After
//    * seek is complete, the position (length) of the byte array is 
//    * incremented (decremented) by the seek amount.
//    * @param w  immutable byte array used for seek
//    * @param offset number of bytes to seek (relative to current position)
//    */
//   public static void seek(ImmutableBytesWritable w, int offset) {
//     w.set(w.get(), w.getOffset() + offset, w.getLength() - offset);
//   }
// }
// 
// Path: orderly-core/src/main/java/orderly/Termination.java
// public enum Termination {
//     AUTO, MUST, SHOULD_NOT
// }


// Path: orderly-core/src/test/java/orderly/RandomRowKeyTestCase.java
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import orderly.Order;
import orderly.RowKeyUtils;
import orderly.Termination;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.junit.Before;
import org.junit.Test;

  public RandomRowKeyTestCase setNumTests(int numTests) {
    this.numTests = numTests;
    return this;
  }

  public RandomRowKeyTestCase setMaxRedZone(int maxRedZone) {
    this.maxRedZone = maxRedZone;
    return this;
  }

  @Override
  public ImmutableBytesWritable allocateBuffer(Object o) throws IOException {
    return new RedZoneImmutableBytesWritable(key.getSerializedLength(o),
        key.getTermination() == Termination.MUST);
  }

  @Override
  public void serialize(Object o, ImmutableBytesWritable w) throws IOException
  {
    byte[] b;
    int len;

    switch(r.nextInt(4)) {
      case 0: /* serialize(Object, ImmutableBytesWritable) */
        key.serialize(o, w);
        break;

      case 1: /* serialize(Object) */
        b = key.serialize(o);
        System.arraycopy(b, 0, w.get(), w.getOffset(), b.length);
        RowKeyUtils.seek(w, b.length);