// Path: src/main/java/com/urbanairship/datacube/Deserializer.java
// public interface Deserializer<O extends Op> {
//     O fromBytes(byte[] bytes);
// }
// 
// Path: src/main/java/com/urbanairship/datacube/Op.java
// public interface Op extends CSerializable {
//     /**
//      * @return an Op that combines the effect of this and otherOp.
//      */
//     Op add(Op otherOp);
// 
//     /**
//      * Return the difference between this op and the given one.
//      *
//      * This should satisfy the following property:
//      * y + x.subtract(y) = x
//      *
//      * This holds for integers, e.g. 10 + (15 - 10) = 15
//      *
//      * An example using LongOp:
//      * assert new LongOp(10).add(new LongOp(15).subtract(10).equals(15)
//      */
//     Op subtract(Op otherOp);
// 
//     /**
//      * Subclasses must override equals() and hashCode().
//      */
//     @Override
//     boolean equals(Object other);
// 
//     @Override
//     int hashCode();
// }
// 
// Path: src/main/java/com/urbanairship/datacube/Util.java
// public class Util {
//     public static byte[] longToBytes(long l) {
//         return ByteBuffer.allocate(8).putLong(l).array();
//     }
// 
//     /**
//      * Write a big-endian integer into the least significant bytes of a byte array.
//      */
//     public static byte[] intToBytesWithLen(int x, int len) {
//         if(len <= 4) {
//             return trailingBytes(intToBytes(x), len);
//         } else {
//             ByteBuffer bb = ByteBuffer.allocate(len);
//             bb.position(len-4);
//             bb.putInt(x);
//             assert bb.remaining() == 0;
//             return bb.array();
//         }
//     }
// 
//     public static long bytesToLong(byte[] bytes) {
//         if(bytes.length < 8) {
//             throw new IllegalArgumentException("Input array was too small: " +
//                     Arrays.toString(bytes));
//         }
//         
//         return ByteBuffer.wrap(bytes).getLong();
//     }
//     
//     /**
//      * Call this if you have a byte array to convert to long, but your array might need
//      * to be left-padded with zeros (if it is less than 8 bytes long). 
//      */
//     public static long bytesToLongPad(byte[] bytes) {
//         final int padZeros = Math.max(8-bytes.length, 0);
//         ByteBuffer bb = ByteBuffer.allocate(8);
//         for(int i=0; i<padZeros; i++) {
//             bb.put((byte)0);
//         }
//         bb.put(bytes, 0, 8-padZeros);
//         bb.flip();
//         return bb.getLong();
//     }
//     
//     public static byte[] intToBytes(int x) {
//         ByteBuffer bb = ByteBuffer.allocate(4);
//         bb.putInt(x);
//         return bb.array();
//     }
// 
//     public static int bytesToInt(byte[] bytes) {
//         return ByteBuffer.wrap(bytes).getInt();
//     }
// 
//     public static byte[] leastSignificantBytes(long l, int numBytes) {
//         byte[] all8Bytes = Util.longToBytes(l);
//         return trailingBytes(all8Bytes, numBytes);
//     }
// 
//     public static byte[] trailingBytes(byte[] bs, int numBytes) {
//         return Arrays.copyOfRange(bs, bs.length-numBytes, bs.length);
//     }
// 
//     /**
//      * A utility to allow hashing of a portion of an array without having to copy it.
//      * @param array
//      * @param startInclusive
//      * @param endExclusive
//      * @return hash byte
//      */
//     public static byte hashByteArray(byte[] array, int startInclusive, int endExclusive) {
//         if (array == null) {
//             return 0;
//         }
// 
//         int range = endExclusive - startInclusive;
//         if (range < 0) {
//             throw new IllegalArgumentException(startInclusive + " > " + endExclusive);
//         }
// 
//         int result = 1;
//         for (int i=startInclusive; i<endExclusive; i++){
//             result = 31 * result + array[i];
//         }
// 
//         return (byte)result;
//     }
//     
//     /**
//      * Only use this for testing/debugging. Inefficient.
//      */
//     public static long countRows(Configuration conf, byte[] tableName) throws IOException {
//         HTable hTable = null;
//         ResultScanner rs = null;
//         long count = 0;
//         try {
//             hTable = new HTable(conf, tableName);
//             rs = hTable.getScanner(new Scan());
//             for(@SuppressWarnings("unused") Result r: rs) {
//                 count++;
//             }
//             return count;
//         } finally {
//             if(hTable != null) {
//                 hTable.close();
//             }
//             if(rs != null) {
//                 rs.close();
//             }
//         }
//     }
// }


import com.urbanairship.datacube.Util;
import com.urbanairship.datacube.Deserializer;
import com.urbanairship.datacube.Op;
        if (!(otherOp instanceof DoubleOp)) {
            throw new RuntimeException();
        }
        return new DoubleOp(val + ((DoubleOp) otherOp).val);
    }

    @Override
    public Op subtract(Op otherOp) {
        if (!(otherOp instanceof DoubleOp)) {
            throw new RuntimeException();
        }
        return new DoubleOp(this.val - ((DoubleOp) otherOp).val);
    }

    @Override
    public int hashCode() {
        long temp = val != +0.0d ? Double.doubleToLongBits(val) : 0L;
        return (int) (temp ^ (temp >>> 32));
    }

    /**
     * Eclipse auto-generated
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
// Path: src/main/java/com/urbanairship/datacube/Deserializer.java
// public interface Deserializer<O extends Op> {
//     O fromBytes(byte[] bytes);
// }
// 
// Path: src/main/java/com/urbanairship/datacube/Op.java
// public interface Op extends CSerializable {
//     /**
//      * @return an Op that combines the effect of this and otherOp.
//      */
//     Op add(Op otherOp);
// 
//     /**
//      * Return the difference between this op and the given one.
//      *
//      * This should satisfy the following property:
//      * y + x.subtract(y) = x
//      *
//      * This holds for integers, e.g. 10 + (15 - 10) = 15
//      *
//      * An example using LongOp:
//      * assert new LongOp(10).add(new LongOp(15).subtract(10).equals(15)
//      */
//     Op subtract(Op otherOp);
// 
//     /**
//      * Subclasses must override equals() and hashCode().
//      */
//     @Override
//     boolean equals(Object other);
// 
//     @Override
//     int hashCode();
// }
// 
// Path: src/main/java/com/urbanairship/datacube/Util.java
// public class Util {
//     public static byte[] longToBytes(long l) {
//         return ByteBuffer.allocate(8).putLong(l).array();
//     }
// 
//     /**
//      * Write a big-endian integer into the least significant bytes of a byte array.
//      */
//     public static byte[] intToBytesWithLen(int x, int len) {
//         if(len <= 4) {
//             return trailingBytes(intToBytes(x), len);
//         } else {
//             ByteBuffer bb = ByteBuffer.allocate(len);
//             bb.position(len-4);
//             bb.putInt(x);
//             assert bb.remaining() == 0;
//             return bb.array();
//         }
//     }
// 
//     public static long bytesToLong(byte[] bytes) {
//         if(bytes.length < 8) {
//             throw new IllegalArgumentException("Input array was too small: " +
//                     Arrays.toString(bytes));
//         }
//         
//         return ByteBuffer.wrap(bytes).getLong();
//     }
//     
//     /**
//      * Call this if you have a byte array to convert to long, but your array might need
//      * to be left-padded with zeros (if it is less than 8 bytes long). 
//      */
//     public static long bytesToLongPad(byte[] bytes) {
//         final int padZeros = Math.max(8-bytes.length, 0);
//         ByteBuffer bb = ByteBuffer.allocate(8);
//         for(int i=0; i<padZeros; i++) {
//             bb.put((byte)0);
//         }
//         bb.put(bytes, 0, 8-padZeros);
//         bb.flip();
//         return bb.getLong();
//     }
//     
//     public static byte[] intToBytes(int x) {
//         ByteBuffer bb = ByteBuffer.allocate(4);
//         bb.putInt(x);
//         return bb.array();
//     }
// 
//     public static int bytesToInt(byte[] bytes) {
//         return ByteBuffer.wrap(bytes).getInt();
//     }
// 
//     public static byte[] leastSignificantBytes(long l, int numBytes) {
//         byte[] all8Bytes = Util.longToBytes(l);
//         return trailingBytes(all8Bytes, numBytes);
//     }
// 
//     public static byte[] trailingBytes(byte[] bs, int numBytes) {
//         return Arrays.copyOfRange(bs, bs.length-numBytes, bs.length);
//     }
// 
//     /**
//      * A utility to allow hashing of a portion of an array without having to copy it.
//      * @param array
//      * @param startInclusive
//      * @param endExclusive
//      * @return hash byte
//      */
//     public static byte hashByteArray(byte[] array, int startInclusive, int endExclusive) {
//         if (array == null) {
//             return 0;
//         }
// 
//         int range = endExclusive - startInclusive;
//         if (range < 0) {
//             throw new IllegalArgumentException(startInclusive + " > " + endExclusive);
//         }
// 
//         int result = 1;
//         for (int i=startInclusive; i<endExclusive; i++){
//             result = 31 * result + array[i];
//         }
// 
//         return (byte)result;
//     }
//     
//     /**
//      * Only use this for testing/debugging. Inefficient.
//      */
//     public static long countRows(Configuration conf, byte[] tableName) throws IOException {
//         HTable hTable = null;
//         ResultScanner rs = null;
//         long count = 0;
//         try {
//             hTable = new HTable(conf, tableName);
//             rs = hTable.getScanner(new Scan());
//             for(@SuppressWarnings("unused") Result r: rs) {
//                 count++;
//             }
//             return count;
//         } finally {
//             if(hTable != null) {
//                 hTable.close();
//             }
//             if(rs != null) {
//                 rs.close();
//             }
//         }
//     }
// }


// Path: src/main/java/com/urbanairship/datacube/ops/DoubleOp.java
import com.urbanairship.datacube.Util;
import com.urbanairship.datacube.Deserializer;
import com.urbanairship.datacube.Op;

        if (!(otherOp instanceof DoubleOp)) {
            throw new RuntimeException();
        }
        return new DoubleOp(val + ((DoubleOp) otherOp).val);
    }

    @Override
    public Op subtract(Op otherOp) {
        if (!(otherOp instanceof DoubleOp)) {
            throw new RuntimeException();
        }
        return new DoubleOp(this.val - ((DoubleOp) otherOp).val);
    }

    @Override
    public int hashCode() {
        long temp = val != +0.0d ? Double.doubleToLongBits(val) : 0L;
        return (int) (temp ^ (temp >>> 32));
    }

    /**
     * Eclipse auto-generated
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;