// Path: src/main/java/org/ardverk/coding/CodingUtils.java
// public class CodingUtils {
// 
//   private CodingUtils() {}
//   
//   /**
//    * Encodes the given {@link String} in Base-2 (binary) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase2(String data) {
//     return encodeBase2(StringUtils.getBytes(data));
//   }
//   
//   /**
//    * Encodes the given byte-array in Base-2 (binary) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase2(byte[] data) {
//     return encodeBase2(data, 0, data.length);
//   }
//   
//   /**
//    * Encodes the given byte-array in Base-2 (binary) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase2(byte[] data, int offset, int length) {
//     return StringUtils.toString(Base2.encodeBase2(data, offset, length));
//   }
// 
//   /**
//    * Encodes the given {@link String} in Base-16 (hex) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase16(String data) {
//     return encodeBase16(StringUtils.getBytes(data));
//   }
//   
//   /**
//    * Encodes the given byte-array in Base-16 (hex) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase16(byte[] data) {
//     return encodeBase16(data, 0, data.length);
//   }
//   
//   /**
//    * Encodes the given byte-array in Base-16 (hex) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase16(byte[] data, int offset, int length) {
//     return StringUtils.toString(Base16.encodeBase16(data, offset, length));
//   }
//   
//   /**
//    * Decodes a Base-16 (hex) encoded {@link String}.
//    */
//   public static byte[] decodeBase16(String data) {
//     return decodeBase16(StringUtils.getBytes(data));
//   }
//   
//   /**
//    * Decodes a Base-16 (hex) encoded value.
//    */
//   public static byte[] decodeBase16(byte[] data) {
//     return decodeBase16(data, 0, data.length);
//   }
//   
//   /**
//    * Decodes a Base-16 (hex) encoded value.
//    */
//   public static byte[] decodeBase16(byte[] data, int offset, int length) {
//     return Base16.decodeBase16(data, offset, length);
//   }
// }
// 
// Path: src/main/java/org/ardverk/io/Streamable.java
// public interface Streamable {
// 
//   /**
//    * Writes this Object to the given {@link OutputStream} and returns
//    * the number of bytes that were written.
//    */
//   public void writeTo(OutputStream out) throws IOException;
// }
// 
// Path: src/main/java/org/ardverk/utils/ByteArrayComparator.java
// public class ByteArrayComparator implements Comparator<byte[]>, Serializable {
// 
//   private static final long serialVersionUID = 6625000716332463624L;
// 
//   public static final ByteArrayComparator COMPARATOR = new ByteArrayComparator();
//   
//   @Override
//   public int compare(byte[] o1, byte[] o2) {
//     if (o1.length != o2.length) {
//       return o1.length - o2.length;
//     }
//     
//     for (int i = 0; i < o1.length; i++) {
//       int diff = Bytes.compareUnsigned(o1[i], o2[i]);
//       if (diff != 0) {
//         return diff;
//       }
//     }
// 
//     return 0;
//   }
// }


import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Arrays;
import org.ardverk.coding.CodingUtils;
import org.ardverk.io.Streamable;
import org.ardverk.utils.ByteArrayComparator;
/*
 * Copyright 2010-2012 Roger Kapsi
 *
 *   Licensed 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.
 */

package org.ardverk.lang;



public class ByteArray<T extends ByteArray<T>> 
    implements Comparable<T>, Streamable, Serializable {
  
  private static final long serialVersionUID = -3599578418695385540L;
  
  protected final byte[] value;
  
  private int hashCode = 0;

  public ByteArray(byte[] value) {
    this.value = value;
  }
  
  /**
   * Returns the length of the {@link ByteArray} in {@code byte}s.
   */
  public int length() {
    return value.length;
  }
  
  /**
   * Returns a copy of the underlying {@code byte[]}.
   */
  public byte[] getBytes() {
    return getBytes(true);
  }
  
  /**
   * Returns the underlying {@code byte[]}.
   */
  public byte[] getBytes(boolean copy) {
    return copy ? value.clone() : value;
  }
  
  /**
   * Copies and returns the underlying {@code byte[]}.
   */
  public byte[] getBytes(byte[] dst, int destPos) {
    assert (dst != value); // Who would be so stupid?
    System.arraycopy(value, 0, dst, destPos, value.length);
    return dst;
  }
  
  @Override
  public void writeTo(OutputStream out) throws IOException {
    out.write(value);
  }
  
  @Override
  public int compareTo(T o) {
// Path: src/main/java/org/ardverk/coding/CodingUtils.java
// public class CodingUtils {
// 
//   private CodingUtils() {}
//   
//   /**
//    * Encodes the given {@link String} in Base-2 (binary) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase2(String data) {
//     return encodeBase2(StringUtils.getBytes(data));
//   }
//   
//   /**
//    * Encodes the given byte-array in Base-2 (binary) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase2(byte[] data) {
//     return encodeBase2(data, 0, data.length);
//   }
//   
//   /**
//    * Encodes the given byte-array in Base-2 (binary) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase2(byte[] data, int offset, int length) {
//     return StringUtils.toString(Base2.encodeBase2(data, offset, length));
//   }
// 
//   /**
//    * Encodes the given {@link String} in Base-16 (hex) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase16(String data) {
//     return encodeBase16(StringUtils.getBytes(data));
//   }
//   
//   /**
//    * Encodes the given byte-array in Base-16 (hex) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase16(byte[] data) {
//     return encodeBase16(data, 0, data.length);
//   }
//   
//   /**
//    * Encodes the given byte-array in Base-16 (hex) and returns it 
//    * as a {@link String}.
//    */
//   public static String encodeBase16(byte[] data, int offset, int length) {
//     return StringUtils.toString(Base16.encodeBase16(data, offset, length));
//   }
//   
//   /**
//    * Decodes a Base-16 (hex) encoded {@link String}.
//    */
//   public static byte[] decodeBase16(String data) {
//     return decodeBase16(StringUtils.getBytes(data));
//   }
//   
//   /**
//    * Decodes a Base-16 (hex) encoded value.
//    */
//   public static byte[] decodeBase16(byte[] data) {
//     return decodeBase16(data, 0, data.length);
//   }
//   
//   /**
//    * Decodes a Base-16 (hex) encoded value.
//    */
//   public static byte[] decodeBase16(byte[] data, int offset, int length) {
//     return Base16.decodeBase16(data, offset, length);
//   }
// }
// 
// Path: src/main/java/org/ardverk/io/Streamable.java
// public interface Streamable {
// 
//   /**
//    * Writes this Object to the given {@link OutputStream} and returns
//    * the number of bytes that were written.
//    */
//   public void writeTo(OutputStream out) throws IOException;
// }
// 
// Path: src/main/java/org/ardverk/utils/ByteArrayComparator.java
// public class ByteArrayComparator implements Comparator<byte[]>, Serializable {
// 
//   private static final long serialVersionUID = 6625000716332463624L;
// 
//   public static final ByteArrayComparator COMPARATOR = new ByteArrayComparator();
//   
//   @Override
//   public int compare(byte[] o1, byte[] o2) {
//     if (o1.length != o2.length) {
//       return o1.length - o2.length;
//     }
//     
//     for (int i = 0; i < o1.length; i++) {
//       int diff = Bytes.compareUnsigned(o1[i], o2[i]);
//       if (diff != 0) {
//         return diff;
//       }
//     }
// 
//     return 0;
//   }
// }


// Path: src/main/java/org/ardverk/lang/ByteArray.java
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Arrays;
import org.ardverk.coding.CodingUtils;
import org.ardverk.io.Streamable;
import org.ardverk.utils.ByteArrayComparator;

/*
 * Copyright 2010-2012 Roger Kapsi
 *
 *   Licensed 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.
 */

package org.ardverk.lang;



public class ByteArray<T extends ByteArray<T>> 
    implements Comparable<T>, Streamable, Serializable {
  
  private static final long serialVersionUID = -3599578418695385540L;
  
  protected final byte[] value;
  
  private int hashCode = 0;

  public ByteArray(byte[] value) {
    this.value = value;
  }
  
  /**
   * Returns the length of the {@link ByteArray} in {@code byte}s.
   */
  public int length() {
    return value.length;
  }
  
  /**
   * Returns a copy of the underlying {@code byte[]}.
   */
  public byte[] getBytes() {
    return getBytes(true);
  }
  
  /**
   * Returns the underlying {@code byte[]}.
   */
  public byte[] getBytes(boolean copy) {
    return copy ? value.clone() : value;
  }
  
  /**
   * Copies and returns the underlying {@code byte[]}.
   */
  public byte[] getBytes(byte[] dst, int destPos) {
    assert (dst != value); // Who would be so stupid?
    System.arraycopy(value, 0, dst, destPos, value.length);
    return dst;
  }
  
  @Override
  public void writeTo(OutputStream out) throws IOException {
    out.write(value);
  }
  
  @Override
  public int compareTo(T o) {
    return ByteArrayComparator.COMPARATOR.compare(value, o.value);