You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2014/03/15 01:26:51 UTC

[03/50] [abbrv] Package re-org.

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/utils/UUIDUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/utils/UUIDUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/utils/UUIDUtils.java
deleted file mode 100644
index 0363cd6..0000000
--- a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/persistence/utils/UUIDUtils.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.usergrid.persistence.utils;
-
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.ReentrantLock;
-
-import com.fasterxml.uuid.EthernetAddress;
-import com.fasterxml.uuid.UUIDComparator;
-
-import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_HI;
-import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_LO;
-import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_MID;
-import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.apache.commons.codec.binary.Base64.decodeBase64;
-import static org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString;
-
-import static org.apache.usergrid.persistence.utils.ConversionUtils.bytes;
-import static org.apache.usergrid.persistence.utils.ConversionUtils.uuid;
-
-
-public class UUIDUtils {
-    private static final Logger LOG = LoggerFactory.getLogger( UUIDUtils.class );
-    private static final int[] MICROS = new int[1000];
-
-
-    static {
-        for ( int x = 0; x < 1000; x++ ) {
-            MICROS[x] = x * 10;
-        }
-    }
-
-
-    private static ReentrantLock tsLock = new ReentrantLock( true );
-
-    public static final UUID MIN_TIME_UUID = UUID.fromString( "00000000-0000-1000-8000-000000000000" );
-
-    public static final UUID MAX_TIME_UUID = UUID.fromString( "ffffffff-ffff-1fff-bfff-ffffffffffff" );
-
-    public static final UUID ZERO_UUID = new UUID( 0, 0 );
-
-    private static long timestampMillisNow = System.currentTimeMillis();
-
-    private static AtomicInteger currentMicrosPoint = new AtomicInteger( 0 );
-    private static AtomicInteger customMicrosPointer = new AtomicInteger( 0 );
-
-
-    /**
-     * Return the "next" UUID in micro second resolution. <b>WARNING</b>: this is designed to return the next unique
-     * timestamped UUID for this JVM. Depending on velocity of the call, this method may block internally to insure that
-     * "now" is kept in sync with the UUIDs being generated by this call.
-     * <p/>
-     * In other words, we will intentionally burn CPU insuring that this method is not executed more than 10k -1 times
-     * per millisecond and guarantee that those microseconds held within are sequential.
-     * <p/>
-     * If we did not do this, you would get <b>timestamp collision</b> even though the UUIDs will technically be
-     * 'unique.'
-     */
-    public static java.util.UUID newTimeUUID() {
-        // get & inc counter, but roll on 1k (because we divide by 10 on retrieval)
-        // if count + currentMicro > 1k, block and roll
-        tsLock.lock();
-        long ts = System.currentTimeMillis();
-        if ( ts > timestampMillisNow ) {
-            timestampMillisNow = ts;
-            currentMicrosPoint.set( 0 );
-        }
-        int pointer = currentMicrosPoint.getAndIncrement();
-        try {
-            if ( pointer > 990 ) {
-                TimeUnit.MILLISECONDS.sleep( 1L );
-            }
-        }
-        catch ( Exception ex ) {
-            ex.printStackTrace();
-        }
-        finally {
-            tsLock.unlock();
-        }
-        return newTimeUUID( ts, MICROS[pointer] );
-    }
-
-
-    private static final long KCLOCK_OFFSET = 0x01b21dd213814000L;
-    private static final long KCLOCK_MULTIPLIER_L = 10000L;
-
-    private static final Random CLOCK_SEQ_RANDOM = new Random();
-
-
-    // 14 bits of randomness
-    private static int getRandomClockSequence() {
-        return CLOCK_SEQ_RANDOM.nextInt() & 0x3FFF;
-    }
-
-
-    private static void setTimestamp( long timestamp, byte[] uuidBytes, int clockSeq, int timeOffset ) {
-
-        timestamp *= KCLOCK_MULTIPLIER_L;
-        timestamp += KCLOCK_OFFSET;
-        timestamp += timeOffset;
-
-        // Set random clock sequence
-        uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] = ( byte ) ( clockSeq >> 8 );
-        uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE + 1] = ( byte ) clockSeq;
-
-        // Set variant
-        uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] &= 0x3F;
-        uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] |= 0x80;
-        setTime( uuidBytes, timestamp );
-    }
-
-
-    @SuppressWarnings("all")
-    private static void setTime( byte[] uuidBytes, long timestamp ) {
-
-        // Time fields aren't nicely split across the UUID, so can't just
-        // linearly dump the stamp:
-        int clockHi = ( int ) ( timestamp >>> 32 );
-        int clockLo = ( int ) timestamp;
-
-        uuidBytes[BYTE_OFFSET_CLOCK_HI] = ( byte ) ( clockHi >>> 24 );
-        uuidBytes[BYTE_OFFSET_CLOCK_HI + 1] = ( byte ) ( clockHi >>> 16 );
-        uuidBytes[BYTE_OFFSET_CLOCK_MID] = ( byte ) ( clockHi >>> 8 );
-        uuidBytes[BYTE_OFFSET_CLOCK_MID + 1] = ( byte ) clockHi;
-
-        uuidBytes[BYTE_OFFSET_CLOCK_LO] = ( byte ) ( clockLo >>> 24 );
-        uuidBytes[BYTE_OFFSET_CLOCK_LO + 1] = ( byte ) ( clockLo >>> 16 );
-        uuidBytes[BYTE_OFFSET_CLOCK_LO + 2] = ( byte ) ( clockLo >>> 8 );
-        uuidBytes[BYTE_OFFSET_CLOCK_LO + 3] = ( byte ) clockLo;
-
-        // Set version
-        uuidBytes[BYTE_OFFSET_CLOCK_HI] &= 0x0F;
-        uuidBytes[BYTE_OFFSET_CLOCK_HI] |= 0x10;
-    }
-
-
-    /**
-     * Generate a timeuuid with the given timestamp in milliseconds and the time offset. Useful when you need to
-     * generate sequential UUIDs for the same period in time. I.E
-     * <p/>
-     * newTimeUUID(1000, 0) <br/> newTimeUUID(1000, 1) <br /> newTimeUUID(1000, 2) <br />
-     * <p/>
-     * etc.
-     * <p/>
-     * Only use this method if you are absolutely sure you need it. When it doubt use the method without the timestamp
-     * offset
-     *
-     * @param ts The timestamp in milliseconds
-     * @param timeoffset The offset, which should always be <= 10000. If you go beyond this range, the millisecond will
-     * be incremented since this is beyond the possible values when coverrting from millis to 1/10 microseconds stored
-     * in the time uuid.
-     */
-    public static UUID newTimeUUID( long ts, int timeoffset ) {
-        if ( ts == 0 ) {
-            return newTimeUUID();
-        }
-
-        byte[] uuidBytes = new byte[16];
-        // 47 bits of randomness
-        EthernetAddress eth = EthernetAddress.constructMulticastAddress();
-        eth.toByteArray( uuidBytes, 10 );
-        setTimestamp( ts, uuidBytes, getRandomClockSequence(), timeoffset );
-
-        return uuid( uuidBytes );
-    }
-
-
-    /**
-     * Generate a new UUID with the given time stamp in milliseconds. This method guarantees that subsequent calls will
-     * be of increasing value chronologically. If a large number of subsequent calls are made to this method (>1000)
-     * with the same timestamp, you will have non-unique temporal values stored in your UUID.
-     */
-    public static UUID newTimeUUID( long ts ) {
-        tsLock.lock();
-        int pointer = customMicrosPointer.getAndIncrement();
-        try {
-            if ( pointer > 990 ) {
-                customMicrosPointer.set( 0 );
-            }
-        }
-        finally {
-            tsLock.unlock();
-        }
-        return newTimeUUID( ts, MICROS[pointer] );
-    }
-
-
-    public static UUID minTimeUUID( long ts ) {
-        byte[] uuidBytes = new byte[16];
-        setTimestamp( ts, uuidBytes, 0, 0 );
-
-        return uuid( uuidBytes );
-    }
-
-
-    public static UUID maxTimeUUID( long ts ) {
-        byte[] uuidBytes = new byte[16];
-        uuidBytes[10] = ( byte ) 0xFF;
-        uuidBytes[11] = ( byte ) 0xFF;
-        uuidBytes[12] = ( byte ) 0xFF;
-        uuidBytes[13] = ( byte ) 0xFF;
-        uuidBytes[14] = ( byte ) 0xFF;
-        uuidBytes[15] = ( byte ) 0xFF;
-        setTimestamp( ts, uuidBytes, 0x3FFF, 0x1FFF );
-
-        return uuid( uuidBytes );
-    }
-
-
-    /** Returns the minimum UUID */
-    public static UUID min( UUID first, UUID second ) {
-        if ( first == null ) {
-            if ( second == null ) {
-                return null;
-            }
-            return second;
-        }
-
-        if ( second == null ) {
-            return first;
-        }
-
-        if ( compare( first, second ) < 0 ) {
-            return first;
-        }
-        return second;
-    }
-
-
-    /** Returns the minimum UUID */
-    public static UUID max( UUID first, UUID second ) {
-        if ( first == null ) {
-            if ( second == null ) {
-                return null;
-            }
-            return second;
-        }
-
-        if ( second == null ) {
-            return first;
-        }
-
-        if ( compare( first, second ) < 0 ) {
-            return second;
-        }
-        return first;
-    }
-
-
-    /** Returns a UUID that is -1 of the passed uuid, sorted by time uuid only */
-    public static UUID decrement( UUID uuid ) {
-        if ( !isTimeBased( uuid ) ) {
-            throw new IllegalArgumentException( "The uuid must be a time type" );
-        }
-
-
-        //timestamp is in the 60 bit timestamp
-        long timestamp = uuid.timestamp();
-        timestamp--;
-
-        if ( timestamp < 0 ) {
-            throw new IllegalArgumentException( "You must specify a time uuid with a timestamp > 0" );
-        }
-
-        //get our bytes, then set the smaller timestamp into it
-        byte[] uuidBytes = bytes( uuid );
-
-        setTime( uuidBytes, timestamp );
-
-        return uuid( uuidBytes );
-    }
-
-
-    public static boolean isTimeBased( UUID uuid ) {
-        if ( uuid == null ) {
-            return false;
-        }
-        return uuid.version() == 1;
-    }
-
-
-    public static long getTimestampInMillis( UUID uuid ) {
-        if ( uuid == null ) {
-            return 0;
-        }
-        long t = uuid.timestamp();
-        return ( t - KCLOCK_OFFSET ) / KCLOCK_MULTIPLIER_L;
-    }
-
-
-    public static long getTimestampInMicros( UUID uuid ) {
-        if ( uuid == null ) {
-            return 0;
-        }
-        long t = uuid.timestamp();
-        return ( t - KCLOCK_OFFSET ) / 10;
-    }
-
-
-    public static UUID tryGetUUID( String s ) {
-        if ( s == null ) {
-            return null;
-        }
-        if ( s.length() != 36 ) {
-            return null;
-        }
-        // 8-4-4-4-12
-        // 0-7,8,9-12,13,14-17,18,19-22,23,24-35
-        if ( s.charAt( 8 ) != '-' ) {
-            return null;
-        }
-        if ( s.charAt( 13 ) != '-' ) {
-            return null;
-        }
-        if ( s.charAt( 18 ) != '-' ) {
-            return null;
-        }
-        if ( s.charAt( 23 ) != '-' ) {
-            return null;
-        }
-        UUID uuid = null;
-        try {
-            uuid = UUID.fromString( s );
-        }
-        catch ( Exception e ) {
-            LOG.info( "Could not convert String {} into a UUID", s, e );
-        }
-        return uuid;
-    }
-
-
-    public static boolean isUUID( String s ) {
-        return tryGetUUID( s ) != null;
-    }
-
-
-    public static UUID tryExtractUUID( String s ) {
-        if ( s == null ) {
-            return null;
-        }
-        if ( s.length() < 36 ) {
-            return null;
-        }
-        return tryGetUUID( s.substring( 0, 36 ) );
-    }
-
-
-    public static UUID tryExtractUUID( String s, int offset ) {
-        if ( s == null ) {
-            return null;
-        }
-        if ( ( s.length() - offset ) < 36 ) {
-            return null;
-        }
-        return tryGetUUID( s.substring( offset, offset + 36 ) );
-    }
-
-
-    public static String toBase64( UUID id ) {
-        if ( id == null ) {
-            return null;
-        }
-        return encodeBase64URLSafeString( bytes( id ) );
-    }
-
-
-    public static UUID fromBase64( String str ) {
-        if ( str == null ) {
-            return null;
-        }
-        byte[] bytes = decodeBase64( str );
-        if ( bytes.length != 16 ) {
-            return null;
-        }
-        return uuid( bytes );
-    }
-
-
-    public static int compare( UUID u1, UUID u2 ) {
-        return UUIDComparator.staticCompare( u1, u2 );
-    }
-
-
-    public static List<UUID> sort( List<UUID> uuids ) {
-        Collections.sort( uuids, new UUIDComparator() );
-        return uuids;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ClassUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ClassUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ClassUtils.java
new file mode 100644
index 0000000..6ce847e
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ClassUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+
+public class ClassUtils extends org.apache.commons.lang.ClassUtils {
+
+    @SuppressWarnings("unchecked")
+    public static <A, B> B cast( A a ) {
+        return ( B ) a;
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private static final Set<Class<?>> WRAPPER_TYPES = new HashSet<Class<?>>(
+            Arrays.asList( Boolean.class, Byte.class, Character.class, Double.class, Float.class, Integer.class,
+                    Long.class, Short.class, Void.class ) );
+
+
+    public static boolean isWrapperType( Class<?> clazz ) {
+        return WRAPPER_TYPES.contains( clazz );
+    }
+
+
+    public static boolean isPrimitiveType( Class<?> clazz ) {
+        if ( clazz == null ) {
+            return false;
+        }
+        return clazz.isPrimitive() || isWrapperType( clazz );
+    }
+
+
+    public static boolean isBasicType( Class<?> clazz ) {
+        if ( clazz == null ) {
+            return false;
+        }
+        return ( String.class.isAssignableFrom( clazz ) ) || isPrimitiveType( clazz );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ConversionUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ConversionUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ConversionUtils.java
new file mode 100644
index 0000000..567a713
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ConversionUtils.java
@@ -0,0 +1,765 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.commons.lang.math.NumberUtils;
+
+
+/** Convenience methods for converting to and from formats, primarily between byte arrays and UUIDs, Strings,
+ * and Longs. */
+public class ConversionUtils {
+
+    private static final Logger logger = LoggerFactory.getLogger( ConversionUtils.class );
+
+    /**
+     *
+     */
+    public static final String UTF8_ENCODING = "UTF-8";
+
+    /**
+     *
+     */
+    public static final String ASCII_ENCODING = "US-ASCII";
+
+    public static final ByteBuffer HOLDER = ByteBuffer.wrap( new byte[] { 0 } );
+
+
+    /**
+     * @param uuid
+     * @return
+     */
+    public static UUID uuid( byte[] uuid ) {
+        return uuid( uuid, 0 );
+    }
+
+
+    /**
+     * @param uuid
+     * @param offset
+     * @return
+     */
+    public static UUID uuid( byte[] uuid, int offset ) {
+        ByteBuffer bb = ByteBuffer.wrap( uuid, offset, 16 );
+        return new UUID( bb.getLong(), bb.getLong() );
+    }
+
+
+    public static UUID uuid( ByteBuffer bb ) {
+        if ( bb == null ) {
+            return null;
+        }
+        if ( bb.remaining() < 16 ) {
+            return null;
+        }
+        bb = bb.slice();
+        return new UUID( bb.getLong(), bb.getLong() );
+    }
+
+
+    /**
+     * @param uuid
+     * @return
+     */
+    public static UUID uuid( String uuid ) {
+        try {
+            return UUID.fromString( uuid );
+        }
+        catch ( Exception e ) {
+            logger.error( "Bad UUID", e );
+        }
+        return UUIDUtils.ZERO_UUID;
+    }
+
+
+    /**
+     * @param obj
+     * @return
+     */
+    public static UUID uuid( Object obj ) {
+        return uuid( obj, UUIDUtils.ZERO_UUID );
+    }
+
+
+    public static UUID uuid( Object obj, UUID defaultValue ) {
+        if ( obj instanceof UUID ) {
+            return ( UUID ) obj;
+        }
+        else if ( obj instanceof byte[] ) {
+            return uuid( ( byte[] ) obj );
+        }
+        else if ( obj instanceof ByteBuffer ) {
+            return uuid( ( ByteBuffer ) obj );
+        }
+        else if ( obj instanceof String ) {
+            return uuid( ( String ) obj );
+        }
+        return defaultValue;
+    }
+
+
+    /**
+     * @param uuid
+     * @return
+     */
+    public static byte[] bytes( UUID uuid ) {
+        if ( uuid == null ) {
+            return null;
+        }
+        long msb = uuid.getMostSignificantBits();
+        long lsb = uuid.getLeastSignificantBits();
+        byte[] buffer = new byte[16];
+
+        for ( int i = 0; i < 8; i++ ) {
+            buffer[i] = ( byte ) ( msb >>> ( 8 * ( 7 - i ) ) );
+        }
+        for ( int i = 8; i < 16; i++ ) {
+            buffer[i] = ( byte ) ( lsb >>> ( 8 * ( 7 - i ) ) );
+        }
+
+        return buffer;
+    }
+
+
+    public static ByteBuffer bytebuffer( UUID uuid ) {
+        if ( uuid == null ) {
+            return null;
+        }
+        return ByteBuffer.wrap( bytes( uuid ) );
+    }
+
+
+    /**
+     * @param uuid
+     * @return
+     */
+    public static byte[] uuidToBytesNullOk( UUID uuid ) {
+        if ( uuid != null ) {
+            return bytes( uuid );
+        }
+        return new byte[16];
+    }
+
+
+    /**
+     * @param s
+     * @return
+     */
+    public static byte[] bytes( String s ) {
+        return bytes( s, UTF8_ENCODING );
+    }
+
+
+    public static ByteBuffer bytebuffer( String s ) {
+        return ByteBuffer.wrap( bytes( s ) );
+    }
+
+
+    /**
+     * @param s
+     * @return
+     */
+    public static byte[] ascii( String s ) {
+        if ( s == null ) {
+            return new byte[0];
+        }
+        return bytes( s, ASCII_ENCODING );
+    }
+
+
+    public ByteBuffer asciibuffer( String s ) {
+        return ByteBuffer.wrap( ascii( s ) );
+    }
+
+
+    /**
+     * @param s
+     * @param encoding
+     * @return
+     */
+    public static byte[] bytes( String s, String encoding ) {
+        try {
+            return s.getBytes( encoding );
+        }
+        catch ( UnsupportedEncodingException e ) {
+            // logger.log(Level.SEVERE, "UnsupportedEncodingException ", e);
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    public static byte[] bytes( ByteBuffer bb ) {
+        byte[] b = new byte[bb.remaining()];
+        bb.duplicate().get( b );
+        return b;
+    }
+
+
+    public static ByteBuffer bytebuffer( String s, String encoding ) {
+        return ByteBuffer.wrap( bytes( s, encoding ) );
+    }
+
+
+    /**
+     * @param b
+     * @return
+     */
+    public static byte[] bytes( Boolean b ) {
+        byte[] bytes = new byte[1];
+        bytes[0] = b ? ( byte ) 1 : 0;
+        return bytes;
+    }
+
+
+    public static ByteBuffer bytebuffer( Boolean b ) {
+        return ByteBuffer.wrap( bytes( b ) );
+    }
+
+
+    /**
+     * @param val
+     * @return
+     */
+    public static byte[] bytes( Long val ) {
+        ByteBuffer buf = ByteBuffer.allocate( 8 );
+        buf.order( ByteOrder.BIG_ENDIAN );
+        buf.putLong( val );
+        return buf.array();
+    }
+
+
+    public static ByteBuffer bytebuffer( Long val ) {
+        ByteBuffer buf = ByteBuffer.allocate( 8 );
+        buf.order( ByteOrder.BIG_ENDIAN );
+        buf.putLong( val );
+        return ( ByteBuffer ) buf.rewind();
+    }
+
+
+    /**
+     * @param obj
+     * @return
+     */
+    public static byte[] bytes( Object obj ) {
+        if ( obj == null ) {
+            return new byte[0];
+        }
+        else if ( obj instanceof byte[] ) {
+            return ( byte[] ) obj;
+        }
+        else if ( obj instanceof Long ) {
+            return bytes( ( Long ) obj );
+        }
+        else if ( obj instanceof String ) {
+            return bytes( ( String ) obj );
+        }
+        else if ( obj instanceof UUID ) {
+            return bytes( ( UUID ) obj );
+        }
+        else if ( obj instanceof Boolean ) {
+            return bytes( ( Boolean ) obj );
+        }
+        else if ( obj instanceof Date ) {
+            return bytes( ( ( Date ) obj ).getTime() );
+        }
+        else {
+            return bytes( obj.toString() );
+        }
+    }
+
+
+    public static ByteBuffer bytebuffer( byte[] bytes ) {
+        return ByteBuffer.wrap( bytes );
+    }
+
+
+    public static ByteBuffer bytebuffer( ByteBuffer bytes ) {
+        return bytes.duplicate();
+    }
+
+
+    public static ByteBuffer bytebuffer( Object obj ) {
+        if ( obj instanceof ByteBuffer ) {
+            return ( ( ByteBuffer ) obj ).duplicate();
+        }
+        return ByteBuffer.wrap( bytes( obj ) );
+    }
+
+
+    public static List<ByteBuffer> bytebuffers( List<?> l ) {
+        List<ByteBuffer> results = new ArrayList<ByteBuffer>( l.size() );
+        for ( Object o : l ) {
+            results.add( bytebuffer( o ) );
+        }
+        return results;
+    }
+
+
+    /**
+     * @param bytes
+     * @return
+     */
+    public static boolean getBoolean( byte[] bytes ) {
+        return bytes[0] != 0;
+    }
+
+
+    public static boolean getBoolean( ByteBuffer bytes ) {
+        return bytes.slice().get() != 0;
+    }
+
+
+    /**
+     * @param bytes
+     * @param offset
+     * @return
+     */
+    public static boolean getBoolean( byte[] bytes, int offset ) {
+        return bytes[offset] != 0;
+    }
+
+
+    public static boolean getBoolean( Object obj ) {
+        if ( obj instanceof Boolean ) {
+            return ( Boolean ) obj;
+        }
+        else if ( obj instanceof String ) {
+            return Boolean.parseBoolean( ( String ) obj );
+        }
+        else if ( obj instanceof Number ) {
+            return ( ( Number ) obj ).longValue() > 0;
+        }
+
+        return false;
+    }
+
+
+    /**
+     * @param obj
+     * @return
+     */
+    public static String string( Object obj ) {
+        if ( obj instanceof String ) {
+            return ( String ) obj;
+        }
+        else if ( obj instanceof byte[] ) {
+            return string( ( byte[] ) obj );
+        }
+        else if ( obj instanceof ByteBuffer ) {
+            return string( ( ByteBuffer ) obj );
+        }
+        else if ( obj != null ) {
+            return obj.toString();
+        }
+        return null;
+    }
+
+
+    /**
+     * @param bytes
+     * @return
+     */
+    public static String string( byte[] bytes ) {
+        if ( bytes == null ) {
+            return null;
+        }
+        return string( bytes, 0, bytes.length, UTF8_ENCODING );
+    }
+
+
+    public static String string( ByteBuffer bytes ) {
+        if ( bytes == null ) {
+            return null;
+        }
+        return string( bytes.array(), bytes.arrayOffset() + bytes.position(), bytes.remaining(), UTF8_ENCODING );
+    }
+
+
+    /**
+     * @param bytes
+     * @param offset
+     * @param length
+     * @return
+     */
+    public static String string( byte[] bytes, int offset, int length ) {
+        return string( bytes, offset, length, UTF8_ENCODING );
+    }
+
+
+    /**
+     * @param bytes
+     * @param offset
+     * @param length
+     * @param encoding
+     * @return
+     */
+    public static String string( byte[] bytes, int offset, int length, String encoding ) {
+
+        if ( length <= 0 ) {
+            return "";
+        }
+
+        if ( bytes == null ) {
+            return "";
+        }
+
+        try {
+            return new String( bytes, offset, length, encoding );
+        }
+        catch ( UnsupportedEncodingException e ) {
+            // logger.log(Level.SEVERE, "UnsupportedEncodingException ", e);
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    public static <T> List<String> strings( Collection<T> items ) {
+        List<String> strings = new ArrayList<String>();
+        for ( T item : items ) {
+            strings.add( string( item ) );
+        }
+        return strings;
+    }
+
+
+    /**
+     * @param bytes
+     * @param offset
+     * @return
+     */
+    public static String stringFromLong( byte[] bytes, int offset ) {
+        if ( bytes.length == 0 ) {
+            return "";
+        }
+        if ( ( bytes.length - offset ) < 8 ) {
+            throw new IllegalArgumentException( "A long is at least 8 bytes" );
+        }
+        return String.valueOf( ByteBuffer.wrap( bytes, offset, 8 ).getLong() );
+    }
+
+
+    /**
+     * @param bytes
+     * @return
+     */
+    public static long getLong( byte[] bytes ) {
+        return ByteBuffer.wrap( bytes, 0, 8 ).getLong();
+    }
+
+
+    public static long getLong( ByteBuffer bytes ) {
+        return bytes.slice().getLong();
+    }
+
+
+    public static long getLong( Object obj ) {
+        if ( obj instanceof Long ) {
+            return ( Long ) obj;
+        }
+        if ( obj instanceof Number ) {
+            return ( ( Number ) obj ).longValue();
+        }
+        if ( obj instanceof String ) {
+            return NumberUtils.toLong( ( String ) obj );
+        }
+        if ( obj instanceof Date ) {
+            return ( ( Date ) obj ).getTime();
+        }
+        if ( obj instanceof byte[] ) {
+            return getLong( ( byte[] ) obj );
+        }
+        if ( obj instanceof ByteBuffer ) {
+            return getLong( ( ByteBuffer ) obj );
+        }
+        return 0;
+    }
+
+
+    /**
+     * @param bytes
+     * @return
+     */
+    public static int getInt( byte[] bytes ) {
+        return ByteBuffer.wrap( bytes, 0, 4 ).getInt();
+    }
+
+
+    public static int getInt( ByteBuffer bytes ) {
+        return bytes.slice().getInt();
+    }
+
+
+    public static int getInt( Object obj ) {
+        if ( obj instanceof Integer ) {
+            return ( Integer ) obj;
+        }
+        if ( obj instanceof Number ) {
+            return ( ( Number ) obj ).intValue();
+        }
+        if ( obj instanceof String ) {
+            return NumberUtils.toInt( ( String ) obj );
+        }
+        if ( obj instanceof Date ) {
+            return ( int ) ( ( Date ) obj ).getTime();
+        }
+        if ( obj instanceof byte[] ) {
+            return getInt( ( byte[] ) obj );
+        }
+        if ( obj instanceof ByteBuffer ) {
+            return getInt( ( ByteBuffer ) obj );
+        }
+        return 0;
+    }
+
+
+    /**
+     * @param bytes
+     * @return
+     */
+    public static float getFloat( byte[] bytes ) {
+        return ByteBuffer.wrap( bytes, 0, 4 ).getFloat();
+    }
+
+
+    public static float getFloat( ByteBuffer bytes ) {
+        return bytes.slice().getFloat();
+    }
+
+
+    public static float getFloat( Object obj ) {
+        if ( obj instanceof Float ) {
+            return ( Float ) obj;
+        }
+        if ( obj instanceof Number ) {
+            return ( ( Number ) obj ).floatValue();
+        }
+        if ( obj instanceof String ) {
+            return NumberUtils.toFloat( ( String ) obj );
+        }
+        if ( obj instanceof Date ) {
+            return ( ( Date ) obj ).getTime();
+        }
+        if ( obj instanceof byte[] ) {
+            return getFloat( ( byte[] ) obj );
+        }
+        if ( obj instanceof ByteBuffer ) {
+            return getFloat( ( ByteBuffer ) obj );
+        }
+        return 0;
+    }
+
+
+    public static double getDouble( byte[] bytes ) {
+        return ByteBuffer.wrap( bytes, 0, 8 ).getDouble();
+    }
+
+
+    public static double getDouble( ByteBuffer bytes ) {
+        return bytes.slice().getDouble();
+    }
+
+
+    public static double getDouble( Object obj ) {
+        if ( obj instanceof Double ) {
+            return ( Double ) obj;
+        }
+        if ( obj instanceof Number ) {
+            return ( ( Number ) obj ).doubleValue();
+        }
+        if ( obj instanceof String ) {
+            return NumberUtils.toDouble( ( String ) obj );
+        }
+        if ( obj instanceof Date ) {
+            return ( ( Date ) obj ).getTime();
+        }
+        if ( obj instanceof byte[] ) {
+            return getDouble( ( byte[] ) obj );
+        }
+        if ( obj instanceof ByteBuffer ) {
+            return getDouble( ( ByteBuffer ) obj );
+        }
+        return 0;
+    }
+
+
+    /**
+     * @param type
+     * @param bytes
+     * @return
+     */
+    public static Object object( Class<?> type, byte[] bytes ) {
+
+        try {
+            if ( Long.class.isAssignableFrom( type ) ) {
+                return getLong( bytes );
+            }
+            else if ( UUID.class.isAssignableFrom( type ) ) {
+                return uuid( bytes );
+            }
+            else if ( String.class.isAssignableFrom( type ) ) {
+                return string( bytes );
+            }
+            else if ( Boolean.class.isAssignableFrom( type ) ) {
+                return getBoolean( bytes );
+            }
+            else if ( Integer.class.isAssignableFrom( type ) ) {
+                return getInt( bytes );
+            }
+            else if ( Double.class.isAssignableFrom( type ) ) {
+                return getDouble( bytes );
+            }
+            else if ( Float.class.isAssignableFrom( type ) ) {
+                return getFloat( bytes );
+            }
+            else if ( byte[].class.isAssignableFrom( type ) ) {
+                return bytes;
+            }
+        }
+        catch ( Exception e ) {
+            logger.error( "Unable to get object from bytes for type " + type.getName(), e );
+        }
+        return null;
+    }
+
+
+    public static Object object( Class<?> type, ByteBuffer bytes ) {
+
+        try {
+            if ( Long.class.isAssignableFrom( type ) ) {
+                return bytes.slice().getLong();
+            }
+            else if ( UUID.class.isAssignableFrom( type ) ) {
+                return uuid( bytes );
+            }
+            else if ( String.class.isAssignableFrom( type ) ) {
+                return string( bytes );
+            }
+            else if ( Boolean.class.isAssignableFrom( type ) ) {
+                return bytes.slice().get() != 0;
+            }
+            else if ( Integer.class.isAssignableFrom( type ) ) {
+                return bytes.slice().getInt();
+            }
+            else if ( Double.class.isAssignableFrom( type ) ) {
+                return bytes.slice().getDouble();
+            }
+            else if ( Float.class.isAssignableFrom( type ) ) {
+                return bytes.slice().getFloat();
+            }
+            else if ( ByteBuffer.class.isAssignableFrom( type ) ) {
+                return bytes.duplicate();
+            }
+            else if ( byte[].class.isAssignableFrom( type ) ) {
+                byte[] b = new byte[bytes.remaining()];
+                bytes.slice().get( b );
+                return b;
+            }
+        }
+        catch ( Exception e ) {
+            logger.error( "Unable to get object from bytes for type " + type.getName(), e );
+        }
+        return null;
+    }
+
+
+    /**
+     * @param bb
+     * @param bytes
+     * @param len
+     * @return
+     */
+    public static ByteBuffer appendToByteBuffer( ByteBuffer bb, byte[] bytes, int len ) {
+        if ( len > bytes.length ) {
+            int pos = bb.position();
+            bb.put( bytes );
+            bb.position( pos + len );
+        }
+        else {
+            bb.put( bytes, 0, len );
+        }
+        return bb;
+    }
+
+
+    public static Object coerce( Class<?> type, Object obj ) {
+
+        if ( obj == null ) {
+            return null;
+        }
+
+        if ( type == null ) {
+            return obj;
+        }
+
+        try {
+            if ( Long.class.isAssignableFrom( type ) ) {
+                return getLong( obj );
+            }
+            else if ( UUID.class.isAssignableFrom( type ) ) {
+                return uuid( obj );
+            }
+            else if ( String.class.isAssignableFrom( type ) ) {
+                return string( obj );
+            }
+            else if ( Boolean.class.isAssignableFrom( type ) ) {
+                return getBoolean( obj );
+            }
+            else if ( Integer.class.isAssignableFrom( type ) ) {
+                return getInt( obj );
+            }
+            else if ( Double.class.isAssignableFrom( type ) ) {
+                return getDouble( obj );
+            }
+            else if ( Float.class.isAssignableFrom( type ) ) {
+                return getFloat( obj );
+            }
+            else if ( byte[].class.isAssignableFrom( type ) ) {
+                return bytes( obj );
+            }
+            else if ( ByteBuffer.class.isAssignableFrom( type ) ) {
+                return bytebuffer( obj );
+            }
+        }
+        catch ( Exception e ) {
+            logger.error( "Unable to get object from bytes for type " + type.getName(), e );
+        }
+        return null;
+    }
+
+
+    public static Map<String, Object> coerceMap( Map<String, Class<?>> types, Map<String, Object> values ) {
+        for ( Map.Entry<String, Object> entry : values.entrySet() ) {
+            if ( types.containsKey( entry.getKey() ) ) {
+                values.put( entry.getKey(), coerce( types.get( entry.getKey() ), entry.getValue() ) );
+            }
+        }
+        return values;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/JsonUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/JsonUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/JsonUtils.java
new file mode 100644
index 0000000..4b3e40d
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/JsonUtils.java
@@ -0,0 +1,329 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.io.File;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.exceptions.JsonReadException;
+import org.apache.usergrid.persistence.exceptions.JsonWriteException;
+//import org.apache.usergrid.persistence.Entity;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.io.JsonStringEncoder;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig.Feature;
+import org.codehaus.jackson.smile.SmileFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.commons.lang.StringUtils.substringAfter;
+
+import static org.apache.usergrid.utils.StringUtils.stringOrSubstringBeforeFirst;
+
+
+public class JsonUtils {
+
+    private static final Logger LOG = LoggerFactory.getLogger( JsonUtils.class );
+
+    static ObjectMapper mapper = new ObjectMapper();
+
+    static SmileFactory smile = new SmileFactory();
+
+    static ObjectMapper smileMapper = new ObjectMapper( smile );
+
+    private static ObjectMapper indentObjectMapper = new ObjectMapper();
+
+
+    static {
+        indentObjectMapper.getSerializationConfig().set( Feature.INDENT_OUTPUT, true );
+    }
+
+
+    /** Converts object to JSON string, throws runtime exception JsonWriteException on failure. */
+    public static String mapToJsonString( Object obj ) {
+        try {
+            return mapper.writeValueAsString( obj );
+        }
+        catch ( Throwable t ) {
+            LOG.debug( "Error generating JSON", t );
+            throw new JsonWriteException( "Error generating JSON", t );
+        }
+    }
+
+
+    /** Converts object to JSON string, throws runtime exception JsonWriteException on failure. */
+    public static String mapToFormattedJsonString( Object obj ) {
+        try {
+            return indentObjectMapper.writeValueAsString( obj );
+        }
+        catch ( Throwable t ) {
+            LOG.debug( "Error generating JSON", t );
+            throw new JsonWriteException( "Error generating JSON", t );
+        }
+    }
+
+
+    /** Parses JSON string  and returns object, throws runtime exception JsonReadException on failure. */
+    public static Object parse( String json ) {
+        try {
+            return mapper.readValue( json, Object.class );
+        }
+        catch ( Throwable t ) {
+            LOG.debug( "Error parsing JSON", t );
+            throw new JsonReadException( "Error parsing JSON", t );
+        }
+    }
+
+
+    public static String quoteString( String s ) {
+        JsonStringEncoder encoder = new JsonStringEncoder();
+        return new String( encoder.quoteAsUTF8( s ) );
+    }
+
+
+    public static ByteBuffer toByteBuffer( Object obj ) {
+        if ( obj == null ) {
+            return null;
+        }
+
+        byte[] bytes = null;
+        try {
+            bytes = smileMapper.writeValueAsBytes( obj );
+        }
+        catch ( Exception e ) {
+            LOG.error( "Error getting SMILE bytes", e );
+        }
+        if ( bytes != null ) {
+            return ByteBuffer.wrap( bytes );
+        }
+        return null;
+    }
+
+
+    public static Object fromByteBuffer( ByteBuffer byteBuffer ) {
+        return fromByteBuffer( byteBuffer, Object.class );
+    }
+
+
+    public static Object fromByteBuffer( ByteBuffer byteBuffer, Class<?> clazz ) {
+        if ( ( byteBuffer == null ) || !byteBuffer.hasRemaining() ) {
+            return null;
+        }
+        if ( clazz == null ) {
+            clazz = Object.class;
+        }
+
+        Object obj = null;
+        try {
+            obj = smileMapper.readValue( byteBuffer.array(), byteBuffer.arrayOffset() + byteBuffer.position(),
+                    byteBuffer.remaining(), clazz );
+        }
+        catch ( Exception e ) {
+            LOG.error( "Error parsing SMILE bytes", e );
+        }
+        return obj;
+    }
+
+
+    public static JsonNode toJsonNode( Object obj ) {
+        if ( obj == null ) {
+            return null;
+        }
+        return mapper.convertValue( obj, JsonNode.class );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static Map<String, Object> toJsonMap( Object obj ) {
+        if ( obj == null ) {
+            return null;
+        }
+
+        return ( Map<String, Object> ) mapper.convertValue( obj, Map.class );
+    }
+
+
+    private static UUID tryConvertToUUID( Object o ) {
+        if ( o instanceof String ) {
+            String s = ( String ) o;
+            if ( s.length() == 36 ) {
+                try {
+                    return UUID.fromString( s );
+                }
+                catch ( IllegalArgumentException e ) {
+                    LOG.warn( "Argument to UUID.fromString({}) was invalid.", s, e );
+                }
+            }
+        }
+        return null;
+    }
+
+
+    public static Object normalizeJsonTree( Object obj ) {
+        if ( obj instanceof Map ) {
+            @SuppressWarnings("unchecked") Map<Object, Object> m = ( Map<Object, Object> ) obj;
+            Object o;
+            UUID uuid;
+            for ( Object k : m.keySet() ) {
+                if ( k instanceof String && ( ( String ) k ).equalsIgnoreCase( "name" ) ) {
+                    continue;
+                }
+
+                o = m.get( k );
+                uuid = tryConvertToUUID( o );
+                if ( uuid != null ) {
+                    m.put( k, uuid );
+                }
+                else if ( o instanceof Integer ) {
+                    m.put( k, ( ( Integer ) o ).longValue() );
+                }
+                else if ( o instanceof BigInteger ) {
+                    m.put( k, ( ( BigInteger ) o ).longValue() );
+                }
+            }
+        }
+        else if ( obj instanceof List ) {
+            @SuppressWarnings("unchecked") List<Object> l = ( List<Object> ) obj;
+            Object o;
+            UUID uuid;
+            for ( int i = 0; i < l.size(); i++ ) {
+                o = l.get( i );
+                uuid = tryConvertToUUID( o );
+                if ( uuid != null ) {
+                    l.set( i, uuid );
+                }
+                else if ( ( o instanceof Map ) || ( o instanceof List ) ) {
+                    normalizeJsonTree( o );
+                }
+                else if ( o instanceof Integer ) {
+                    l.set( i, ( ( Integer ) o ).longValue() );
+                }
+                else if ( o instanceof BigInteger ) {
+                    l.set( i, ( ( BigInteger ) o ).longValue() );
+                }
+            }
+        }
+        else if ( obj instanceof String ) {
+            UUID uuid = tryConvertToUUID( obj );
+            if ( uuid != null ) {
+                return uuid;
+            }
+        }
+        else if ( obj instanceof Integer ) {
+            return ( ( Integer ) obj ).longValue();
+        }
+        else if ( obj instanceof BigInteger ) {
+            return ( ( BigInteger ) obj ).longValue();
+        }
+        else if ( obj instanceof JsonNode ) {
+            return mapper.convertValue( obj, Object.class );
+        }
+        return obj;
+    }
+
+
+//    public static Object select( Object obj, String path ) {
+//        return select( obj, path, false );
+//    }
+//
+//
+//    public static Object select( Object obj, String path, boolean buildResultTree ) {
+//
+//        if ( obj == null ) {
+//            return null;
+//        }
+//
+//        if ( org.apache.commons.lang.StringUtils.isBlank( path ) ) {
+//            return obj;
+//        }
+//
+//        String segment = stringOrSubstringBeforeFirst( path, '.' );
+//        String remaining = substringAfter( path, "." );
+//
+//        if ( obj instanceof Map ) {
+//            Map<?, ?> map = ( Map<?, ?> ) obj;
+//            Object child = map.get( segment );
+//            Object result = select( child, remaining, buildResultTree );
+//            if ( result != null ) {
+//                if ( buildResultTree ) {
+//                    Map<Object, Object> results = new LinkedHashMap<Object, Object>();
+//                    results.put( segment, result );
+//                    return results;
+//                }
+//                else {
+//                    return result;
+//                }
+//            }
+//            return null;
+//        }
+//        if ( obj instanceof List ) {
+//            List<Object> results = new ArrayList<Object>();
+//            List<?> list = ( List<?> ) obj;
+//            for ( Object i : list ) {
+//                Object result = select( i, path, buildResultTree );
+//                if ( result != null ) {
+//                    results.add( result );
+//                }
+//            }
+//            if ( !results.isEmpty() ) {
+//                return results;
+//            }
+//            return null;
+//        }
+//
+//        if ( obj instanceof Entity ) {
+//            Object child = ( ( Entity ) obj ).getProperty( segment );
+//            Object result = select( child, remaining, buildResultTree );
+//            if ( result != null ) {
+//                if ( buildResultTree ) {
+//                    Map<Object, Object> results = new LinkedHashMap<Object, Object>();
+//                    results.put( segment, result );
+//                    return results;
+//                }
+//                else {
+//                    return result;
+//                }
+//            }
+//            else {
+//                return result;
+//            }
+//        }
+//
+//        return obj;
+//    }
+
+
+    public static Object loadFromFilesystem( String filename ) {
+        Object json = null;
+        try {
+            File file = new File( filename );
+            json = mapper.readValue( file, Object.class );
+        }
+        catch ( Exception e ) {
+            LOG.error( "Error loading JSON", e );
+        }
+        return json;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ListUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ListUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ListUtils.java
new file mode 100644
index 0000000..db56cdd
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/ListUtils.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.commons.lang.math.NumberUtils;
+import org.apache.usergrid.persistence.collection.util.EntityUtils;
+import org.apache.usergrid.persistence.model.entity.Id;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ListUtils extends org.apache.commons.collections.ListUtils {
+    private static final Logger LOG = LoggerFactory.getLogger( ListUtils.class );
+
+
+    public static <A> A first( List<A> list ) {
+        if ( list == null ) {
+            return null;
+        }
+        if ( list.size() == 0 ) {
+            return null;
+        }
+        return list.get( 0 );
+    }
+
+
+    public static <A> A last( List<A> list ) {
+        if ( list == null ) {
+            return null;
+        }
+        if ( list.size() == 0 ) {
+            return null;
+        }
+        return list.get( list.size() - 1 );
+    }
+
+
+    public static <A> Integer firstInteger( List<A> list ) {
+        A a = first( list );
+        if ( a == null ) {
+            return null;
+        }
+
+        if ( a instanceof Integer ) {
+            return ( Integer ) a;
+        }
+
+        try {
+            return NumberUtils.toInt( ( String ) a );
+        }
+        catch ( Exception e ) {
+            LOG.warn( "Could not convert list item {} to int", a, e );
+        }
+        return null;
+    }
+
+
+    public static <A> Long firstLong( List<A> list ) {
+        A a = first( list );
+        if ( a == null ) {
+            return null;
+        }
+
+        if ( a instanceof Long ) {
+            return ( Long ) a;
+        }
+
+        try {
+            return NumberUtils.toLong( ( String ) a );
+        }
+        catch ( Exception e ) {
+            LOG.warn( "Could not convert list item {} to long", a, e );
+        }
+        return null;
+    }
+
+
+    public static <A> Boolean firstBoolean( List<A> list ) {
+        A a = first( list );
+        if ( a == null ) {
+            return null;
+        }
+
+        if ( a instanceof Boolean ) {
+            return ( Boolean ) a;
+        }
+
+        try {
+            return Boolean.parseBoolean( ( String ) a );
+        }
+        catch ( Exception e ) {
+            LOG.warn( "Could not convert list item {} to boolean", a, e );
+        }
+        return null;
+    }
+
+
+    public static <A> UUID firstUuid( List<A> list ) {
+        A i = first( list );
+        if ( i == null ) {
+            return null;
+        }
+
+        if ( i instanceof UUID ) {
+            return ( UUID ) i;
+        }
+
+        try {
+            return UUIDUtils.tryGetUUID( ( String ) i );
+        }
+        catch ( Exception e ) {
+            LOG.warn( "Could not convert list item {} to UUID", i, e );
+        }
+        return null;
+    }
+
+
+    public static boolean isEmpty( List<?> list ) {
+        return ( list == null ) || ( list.size() == 0 );
+    }
+
+
+    public static <T> List<T> dequeueCopy( List<T> list ) {
+        if ( !isEmpty( list ) ) {
+            list = list.subList( 1, list.size() );
+        }
+        return list;
+    }
+
+
+    public static <T> List<T> initCopy( List<T> list ) {
+        if ( !isEmpty( list ) ) {
+            list = new ArrayList<T>( list );
+        }
+        else {
+            list = new ArrayList<T>();
+        }
+        return list;
+    }
+
+
+    public static <T> T dequeue( List<T> list ) {
+        if ( !isEmpty( list ) ) {
+            return list.remove( 0 );
+        }
+        return null;
+    }
+
+
+    public static <T> List<T> queue( List<T> list, T item ) {
+        if ( list == null ) {
+            list = new ArrayList<T>();
+        }
+        list.add( item );
+        return list;
+    }
+
+
+    public static <T> List<T> requeue( List<T> list, T item ) {
+        if ( list == null ) {
+            list = new ArrayList<T>();
+        }
+        list.add( 0, item );
+        return list;
+    }
+
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public static List<?> flatten( Collection<?> l ) {
+        boolean hasCollection = false;
+        for ( Object o : l ) {
+            if ( o instanceof Collection ) {
+                hasCollection = true;
+                break;
+            }
+        }
+        if ( !hasCollection && ( l instanceof List ) ) {
+            return ( List<?> ) l;
+        }
+        List newList = new ArrayList();
+        for ( Object o : l ) {
+            if ( o instanceof List ) {
+                newList.addAll( flatten( ( List ) o ) );
+            }
+            else {
+                newList.add( o );
+            }
+        }
+        return newList;
+    }
+
+
+    public static boolean anyNull( List<?> l ) {
+        for ( Object o : l ) {
+            if ( o == null ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    public static boolean anyNull( Object... objects ) {
+        for ( Object o : objects ) {
+            if ( o == null ) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/MapUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/MapUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/MapUtils.java
new file mode 100644
index 0000000..12da2e0
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/MapUtils.java
@@ -0,0 +1,377 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+
+import static org.apache.usergrid.utils.ClassUtils.cast;
+
+
+public class MapUtils extends org.apache.commons.collections.MapUtils {
+
+    public static <A, B> void addMapSet( Map<A, Set<B>> map, A a, B b ) {
+        addMapSet( map, false, a, b );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static <A, B> void addMapSet( Map<A, Set<B>> map, boolean ignoreCase, A a, B b ) {
+
+        Set<B> setB = map.get( a );
+        if ( setB == null ) {
+            if ( ignoreCase && ( b instanceof String ) ) {
+                setB = ( Set<B> ) new TreeSet<String>( String.CASE_INSENSITIVE_ORDER );
+            }
+            else {
+                setB = new LinkedHashSet<B>();
+            }
+            map.put( a, setB );
+        }
+        setB.add( b );
+    }
+
+
+    public static <A, B, C> void addMapMapSet( Map<A, Map<B, Set<C>>> map, A a, B b, C c ) {
+        addMapMapSet( map, false, a, b, c );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static <A, B, C> void addMapMapSet( Map<A, Map<B, Set<C>>> map, boolean ignoreCase, A a, B b, C c ) {
+
+        Map<B, Set<C>> mapB = map.get( a );
+        if ( mapB == null ) {
+            if ( ignoreCase && ( b instanceof String ) ) {
+                mapB = ( Map<B, Set<C>> ) new TreeMap<String, Set<C>>( String.CASE_INSENSITIVE_ORDER );
+            }
+            else {
+                mapB = new LinkedHashMap<B, Set<C>>();
+            }
+            map.put( a, mapB );
+        }
+        addMapSet( mapB, ignoreCase, b, c );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static <A, B, C, D> void addMapMapMapSet( Map<A, Map<B, Map<C, Set<D>>>> map, boolean ignoreCase, A a, B b,
+                                                     C c, D d ) {
+        Map<B, Map<C, Set<D>>> mapB = map.get( a );
+        if ( mapB == null ) {
+            if ( ignoreCase && ( b instanceof String ) ) {
+                mapB = ( Map<B, Map<C, Set<D>>> ) new TreeMap<String, Map<C, Set<D>>>( String.CASE_INSENSITIVE_ORDER );
+            }
+            else {
+                mapB = new LinkedHashMap<B, Map<C, Set<D>>>();
+            }
+            map.put( a, mapB );
+        }
+        addMapMapSet( mapB, ignoreCase, b, c, d );
+    }
+
+
+    public static <A, B, C> C getMapMap( Map<A, Map<B, C>> map, A a, B b ) {
+
+        Map<B, C> mapB = map.get( a );
+        if ( mapB == null ) {
+            return null;
+        }
+        return mapB.get( b );
+    }
+
+
+    public static <A, B> void addMapList( Map<A, List<B>> map, A a, B b ) {
+
+        List<B> listB = map.get( a );
+        if ( listB == null ) {
+            listB = new ArrayList<B>();
+            map.put( a, listB );
+        }
+        listB.add( b );
+    }
+
+
+    public static <A, B> void addListToMapList( Map<A, List<B>> map, A a, List<B> b ) {
+
+        List<B> listB = map.get( a );
+        if ( listB == null ) {
+            listB = new ArrayList<B>();
+            map.put( a, listB );
+        }
+        listB.addAll( b );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static <K, V> V getValue( Map<K, ?> map, K k ) {
+        V v = null;
+        try {
+            v = ( V ) map.get( k );
+        }
+        catch ( ClassCastException e ) {
+            //LOG.war( "Map value {} was not the expected class", map.get( k ), e );
+        }
+
+        return v;
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static <K, V> Map<?, ?> map( Object... objects ) {
+        Map<K, V> map = new LinkedHashMap<K, V>();
+        int i = 0;
+        while ( i < objects.length ) {
+            if ( objects[i] instanceof Map.Entry ) {
+                Map.Entry<K, V> entry = ( Entry<K, V> ) objects[i];
+                map.put( entry.getKey(), entry.getValue() );
+                i++;
+            }
+            else if ( objects[i] instanceof Map ) {
+                map.putAll( ( Map<? extends K, ? extends V> ) objects[i] );
+                i++;
+            }
+            else if ( i < ( objects.length - 1 ) ) {
+                K k = ( K ) objects[i];
+                V v = ( V ) objects[i + 1];
+                map.put( k, v );
+                i += 2;
+            }
+            else {
+                break;
+            }
+        }
+        return map;
+    }
+
+
+    private static class SimpleMapEntry<K, V> implements Map.Entry<K, V> {
+
+        private final K k;
+        private V v;
+
+
+        public SimpleMapEntry( K k, V v ) {
+            this.k = k;
+            this.v = v;
+        }
+
+
+        @Override
+        public K getKey() {
+            return k;
+        }
+
+
+        @Override
+        public V getValue() {
+            return v;
+        }
+
+
+        @Override
+        public V setValue( V v ) {
+            V oldV = this.v;
+            this.v = v;
+            return oldV;
+        }
+    }
+
+
+    public static <K, V> Map.Entry<K, V> entry( K k, V v ) {
+        return new SimpleMapEntry<K, V>( k, v );
+    }
+
+
+    public static <K, V> K getFirstKey( Map<K, V> map ) {
+        if ( map == null ) {
+            return null;
+        }
+        Entry<K, V> e = map.entrySet().iterator().next();
+        if ( e != null ) {
+            return e.getKey();
+        }
+        return null;
+    }
+
+
+    public static <V> Map<String, V> filter( Map<String, V> map, String prefix, boolean removePrefix ) {
+        Map<String, V> filteredMap = new LinkedHashMap<String, V>();
+        for ( Entry<String, V> entry : map.entrySet() ) {
+            if ( entry.getKey().startsWith( prefix ) ) {
+                if ( removePrefix ) {
+                    filteredMap.put( entry.getKey().substring( prefix.length() ), entry.getValue() );
+                }
+                else {
+                    filteredMap.put( entry.getKey(), entry.getValue() );
+                }
+            }
+        }
+        return filteredMap;
+    }
+
+
+    public static <V> Map<String, V> filter( Map<String, V> map, String prefix ) {
+        return filter( map, prefix, false );
+    }
+
+
+    public static Properties filter( Properties properties, String prefix, boolean removePrefix ) {
+        Properties filteredProperties = new Properties();
+        for ( Entry<String, String> entry : asMap( properties ).entrySet() ) {
+            if ( entry.getKey().startsWith( prefix ) ) {
+                if ( removePrefix ) {
+                    filteredProperties.put( entry.getKey().substring( prefix.length() ), entry.getValue() );
+                }
+                else {
+                    filteredProperties.put( entry.getKey(), entry.getValue() );
+                }
+            }
+        }
+        return filteredProperties;
+    }
+
+
+    public static Properties filter( Properties properties, String prefix ) {
+        return filter( properties, prefix, false );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static Map<String, String> asMap( Properties properties ) {
+        return cast( properties );
+    }
+
+
+    public static <S, T> HashMapBuilder<S, T> hashMap( S key, T value ) {
+        return new HashMapBuilder<S, T>().map( key, value );
+    }
+
+
+    public static class HashMapBuilder<S, T> extends HashMap<S, T> {
+        private static final long serialVersionUID = 1L;
+
+
+        public HashMapBuilder() {
+        }
+
+
+        public HashMapBuilder<S, T> map( S key, T value ) {
+            put( key, value );
+            return this;
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static Map<String, List<?>> toMapList( Map<String, ?> m ) {
+        Map<String, List<Object>> mapList = new LinkedHashMap<String, List<Object>>();
+
+        for ( Entry<String, ?> e : m.entrySet() ) {
+            if ( e.getValue() instanceof List ) {
+                addListToMapList( mapList, e.getKey(), ( List<Object> ) e.getValue() );
+            }
+            else {
+                addMapList( mapList, e.getKey(), e.getValue() );
+            }
+        }
+
+        return cast( mapList );
+    }
+
+
+    public static Map<String, ?> putPath( String path, Object value ) {
+        return putPath( null, path, value );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static Map<String, ?> putPath( Map<String, ?> map, String path, Object value ) {
+
+        if ( map == null ) {
+            map = new HashMap<String, Object>();
+        }
+
+        int i = path.indexOf( '.' );
+        if ( i < 0 ) {
+            ( ( Map<String, Object> ) map ).put( path, value );
+            return map;
+        }
+        String segment = path.substring( 0, i ).trim();
+        if ( isNotBlank( segment ) ) {
+            Object o = map.get( segment );
+            if ( ( o != null ) && ( !( o instanceof Map ) ) ) {
+                return map;
+            }
+            Map<String, Object> subMap = ( Map<String, Object> ) o;
+            if ( subMap == null ) {
+                subMap = new HashMap<String, Object>();
+                ( ( Map<String, Object> ) map ).put( segment, subMap );
+            }
+            String subPath = path.substring( i + 1 );
+            if ( isNotBlank( subPath ) ) {
+                putPath( subMap, subPath, value );
+            }
+        }
+
+        return map;
+    }
+
+
+    public static <K, V> Map<K, V> emptyMapWithKeys( Map<K, V> map ) {
+        Map<K, V> newMap = new HashMap<K, V>();
+
+        for ( K k : map.keySet() ) {
+            newMap.put( k, null );
+        }
+
+        return newMap;
+    }
+
+
+    public static boolean hasKeys( Map<?, ?> map, String... keys ) {
+        if ( map == null ) {
+            return false;
+        }
+        for ( String key : keys ) {
+            if ( !map.containsKey( key ) ) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    public static boolean hasKeys( Map<?, ?> map, Set<String> keys ) {
+        if ( map == null ) {
+            return false;
+        }
+        return map.keySet().containsAll( keys );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/StringUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/StringUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/StringUtils.java
new file mode 100644
index 0000000..5f64ef3
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/StringUtils.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.util.Arrays;
+
+import org.apache.commons.io.IOUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.usergrid.utils.ConversionUtils.string;
+
+
+public class StringUtils extends org.apache.commons.lang.StringUtils {
+
+    private static final Logger LOG = LoggerFactory.getLogger( StringUtils.class );
+
+
+    public static Object lower( Object obj ) {
+        if ( !( obj instanceof String ) ) {
+            return obj;
+        }
+        return ( ( String ) obj ).toLowerCase();
+    }
+
+
+    public static String stringOrSubstringAfterLast( String str, char c ) {
+        if ( str == null ) {
+            return null;
+        }
+        int i = str.lastIndexOf( c );
+        if ( i != -1 ) {
+            return str.substring( i + 1 );
+        }
+        return str;
+    }
+
+
+    public static String stringOrSubstringBeforeLast( String str, char c ) {
+        if ( str == null ) {
+            return null;
+        }
+        int i = str.lastIndexOf( c );
+        if ( i != -1 ) {
+            return str.substring( 0, i );
+        }
+        return str;
+    }
+
+
+    public static String stringOrSubstringBeforeFirst( String str, char c ) {
+        if ( str == null ) {
+            return null;
+        }
+        int i = str.indexOf( c );
+        if ( i != -1 ) {
+            return str.substring( 0, i );
+        }
+        return str;
+    }
+
+
+    public static String stringOrSubstringAfterFirst( String str, char c ) {
+        if ( str == null ) {
+            return null;
+        }
+        int i = str.indexOf( c );
+        if ( i != -1 ) {
+            return str.substring( i + 1 );
+        }
+        return str;
+    }
+
+
+    public static String compactWhitespace( String str ) {
+        if ( str == null ) {
+            return null;
+        }
+        boolean prevWS = false;
+        StringBuilder builder = new StringBuilder();
+        for ( int i = 0; i < str.length(); i++ ) {
+            char c = str.charAt( i );
+            if ( Character.isWhitespace( c ) ) {
+                if ( !prevWS ) {
+                    builder.append( ' ' );
+                }
+                prevWS = true;
+            }
+            else {
+                prevWS = false;
+                builder.append( c );
+            }
+        }
+        return builder.toString().trim();
+    }
+
+
+    /** @return new string with replace applied */
+    public static String replaceAll( String source, String find, String replace ) {
+        if ( source == null ) {
+            return null;
+        }
+        while ( true ) {
+            String old = source;
+            source = source.replaceAll( find, replace );
+            if ( source.equals( old ) ) {
+                return source;
+            }
+        }
+    }
+
+
+    public static String toString( Object obj ) {
+        return string( obj );
+    }
+
+
+    public static String toStringFormat( Object obj, String format ) {
+        if ( obj != null ) {
+            if ( format != null ) {
+                if ( obj.getClass().isArray() ) {
+                    return String.format( format, Arrays.toString( ( Object[] ) obj ) );
+                }
+                return String.format( format, string( obj ) );
+            }
+            else {
+                return string( obj );
+            }
+        }
+        return "";
+    }
+
+
+    public static boolean isString( Object obj ) {
+        return obj instanceof String;
+    }
+
+
+    public static boolean isStringOrNull( Object obj ) {
+        if ( obj == null ) {
+            return true;
+        }
+        return obj instanceof String;
+    }
+
+
+    public static String readClasspathFileAsString( String filePath ) {
+        try {
+            return IOUtils.toString( StringUtils.class.getResourceAsStream( filePath ) );
+        }
+        catch ( Exception e ) {
+            LOG.error( "Error getting file from classpath: " + filePath, e );
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/UUIDUtils.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/UUIDUtils.java b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/UUIDUtils.java
new file mode 100644
index 0000000..6d8175c
--- /dev/null
+++ b/stack/corepersistence/queryindex/src/main/java/org/apache/usergrid/utils/UUIDUtils.java
@@ -0,0 +1,412 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.usergrid.utils;
+
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReentrantLock;
+
+import com.fasterxml.uuid.EthernetAddress;
+import com.fasterxml.uuid.UUIDComparator;
+
+import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_HI;
+import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_LO;
+import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_MID;
+import static com.fasterxml.uuid.impl.UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.commons.codec.binary.Base64.decodeBase64;
+import static org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString;
+
+import static org.apache.usergrid.utils.ConversionUtils.bytes;
+import static org.apache.usergrid.utils.ConversionUtils.uuid;
+
+
+public class UUIDUtils {
+    private static final Logger LOG = LoggerFactory.getLogger( UUIDUtils.class );
+    private static final int[] MICROS = new int[1000];
+
+
+    static {
+        for ( int x = 0; x < 1000; x++ ) {
+            MICROS[x] = x * 10;
+        }
+    }
+
+
+    private static ReentrantLock tsLock = new ReentrantLock( true );
+
+    public static final UUID MIN_TIME_UUID = UUID.fromString( "00000000-0000-1000-8000-000000000000" );
+
+    public static final UUID MAX_TIME_UUID = UUID.fromString( "ffffffff-ffff-1fff-bfff-ffffffffffff" );
+
+    public static final UUID ZERO_UUID = new UUID( 0, 0 );
+
+    private static long timestampMillisNow = System.currentTimeMillis();
+
+    private static AtomicInteger currentMicrosPoint = new AtomicInteger( 0 );
+    private static AtomicInteger customMicrosPointer = new AtomicInteger( 0 );
+
+
+    /**
+     * Return the "next" UUID in micro second resolution. <b>WARNING</b>: this is designed to return the next unique
+     * timestamped UUID for this JVM. Depending on velocity of the call, this method may block internally to insure that
+     * "now" is kept in sync with the UUIDs being generated by this call.
+     * <p/>
+     * In other words, we will intentionally burn CPU insuring that this method is not executed more than 10k -1 times
+     * per millisecond and guarantee that those microseconds held within are sequential.
+     * <p/>
+     * If we did not do this, you would get <b>timestamp collision</b> even though the UUIDs will technically be
+     * 'unique.'
+     */
+    public static java.util.UUID newTimeUUID() {
+        // get & inc counter, but roll on 1k (because we divide by 10 on retrieval)
+        // if count + currentMicro > 1k, block and roll
+        tsLock.lock();
+        long ts = System.currentTimeMillis();
+        if ( ts > timestampMillisNow ) {
+            timestampMillisNow = ts;
+            currentMicrosPoint.set( 0 );
+        }
+        int pointer = currentMicrosPoint.getAndIncrement();
+        try {
+            if ( pointer > 990 ) {
+                TimeUnit.MILLISECONDS.sleep( 1L );
+            }
+        }
+        catch ( Exception ex ) {
+            ex.printStackTrace();
+        }
+        finally {
+            tsLock.unlock();
+        }
+        return newTimeUUID( ts, MICROS[pointer] );
+    }
+
+
+    private static final long KCLOCK_OFFSET = 0x01b21dd213814000L;
+    private static final long KCLOCK_MULTIPLIER_L = 10000L;
+
+    private static final Random CLOCK_SEQ_RANDOM = new Random();
+
+
+    // 14 bits of randomness
+    private static int getRandomClockSequence() {
+        return CLOCK_SEQ_RANDOM.nextInt() & 0x3FFF;
+    }
+
+
+    private static void setTimestamp( long timestamp, byte[] uuidBytes, int clockSeq, int timeOffset ) {
+
+        timestamp *= KCLOCK_MULTIPLIER_L;
+        timestamp += KCLOCK_OFFSET;
+        timestamp += timeOffset;
+
+        // Set random clock sequence
+        uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] = ( byte ) ( clockSeq >> 8 );
+        uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE + 1] = ( byte ) clockSeq;
+
+        // Set variant
+        uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] &= 0x3F;
+        uuidBytes[BYTE_OFFSET_CLOCK_SEQUENCE] |= 0x80;
+        setTime( uuidBytes, timestamp );
+    }
+
+
+    @SuppressWarnings("all")
+    private static void setTime( byte[] uuidBytes, long timestamp ) {
+
+        // Time fields aren't nicely split across the UUID, so can't just
+        // linearly dump the stamp:
+        int clockHi = ( int ) ( timestamp >>> 32 );
+        int clockLo = ( int ) timestamp;
+
+        uuidBytes[BYTE_OFFSET_CLOCK_HI] = ( byte ) ( clockHi >>> 24 );
+        uuidBytes[BYTE_OFFSET_CLOCK_HI + 1] = ( byte ) ( clockHi >>> 16 );
+        uuidBytes[BYTE_OFFSET_CLOCK_MID] = ( byte ) ( clockHi >>> 8 );
+        uuidBytes[BYTE_OFFSET_CLOCK_MID + 1] = ( byte ) clockHi;
+
+        uuidBytes[BYTE_OFFSET_CLOCK_LO] = ( byte ) ( clockLo >>> 24 );
+        uuidBytes[BYTE_OFFSET_CLOCK_LO + 1] = ( byte ) ( clockLo >>> 16 );
+        uuidBytes[BYTE_OFFSET_CLOCK_LO + 2] = ( byte ) ( clockLo >>> 8 );
+        uuidBytes[BYTE_OFFSET_CLOCK_LO + 3] = ( byte ) clockLo;
+
+        // Set version
+        uuidBytes[BYTE_OFFSET_CLOCK_HI] &= 0x0F;
+        uuidBytes[BYTE_OFFSET_CLOCK_HI] |= 0x10;
+    }
+
+
+    /**
+     * Generate a timeuuid with the given timestamp in milliseconds and the time offset. Useful when you need to
+     * generate sequential UUIDs for the same period in time. I.E
+     * <p/>
+     * newTimeUUID(1000, 0) <br/> newTimeUUID(1000, 1) <br /> newTimeUUID(1000, 2) <br />
+     * <p/>
+     * etc.
+     * <p/>
+     * Only use this method if you are absolutely sure you need it. When it doubt use the method without the timestamp
+     * offset
+     *
+     * @param ts The timestamp in milliseconds
+     * @param timeoffset The offset, which should always be <= 10000. If you go beyond this range, the millisecond will
+     * be incremented since this is beyond the possible values when coverrting from millis to 1/10 microseconds stored
+     * in the time uuid.
+     */
+    public static UUID newTimeUUID( long ts, int timeoffset ) {
+        if ( ts == 0 ) {
+            return newTimeUUID();
+        }
+
+        byte[] uuidBytes = new byte[16];
+        // 47 bits of randomness
+        EthernetAddress eth = EthernetAddress.constructMulticastAddress();
+        eth.toByteArray( uuidBytes, 10 );
+        setTimestamp( ts, uuidBytes, getRandomClockSequence(), timeoffset );
+
+        return uuid( uuidBytes );
+    }
+
+
+    /**
+     * Generate a new UUID with the given time stamp in milliseconds. This method guarantees that subsequent calls will
+     * be of increasing value chronologically. If a large number of subsequent calls are made to this method (>1000)
+     * with the same timestamp, you will have non-unique temporal values stored in your UUID.
+     */
+    public static UUID newTimeUUID( long ts ) {
+        tsLock.lock();
+        int pointer = customMicrosPointer.getAndIncrement();
+        try {
+            if ( pointer > 990 ) {
+                customMicrosPointer.set( 0 );
+            }
+        }
+        finally {
+            tsLock.unlock();
+        }
+        return newTimeUUID( ts, MICROS[pointer] );
+    }
+
+
+    public static UUID minTimeUUID( long ts ) {
+        byte[] uuidBytes = new byte[16];
+        setTimestamp( ts, uuidBytes, 0, 0 );
+
+        return uuid( uuidBytes );
+    }
+
+
+    public static UUID maxTimeUUID( long ts ) {
+        byte[] uuidBytes = new byte[16];
+        uuidBytes[10] = ( byte ) 0xFF;
+        uuidBytes[11] = ( byte ) 0xFF;
+        uuidBytes[12] = ( byte ) 0xFF;
+        uuidBytes[13] = ( byte ) 0xFF;
+        uuidBytes[14] = ( byte ) 0xFF;
+        uuidBytes[15] = ( byte ) 0xFF;
+        setTimestamp( ts, uuidBytes, 0x3FFF, 0x1FFF );
+
+        return uuid( uuidBytes );
+    }
+
+
+    /** Returns the minimum UUID */
+    public static UUID min( UUID first, UUID second ) {
+        if ( first == null ) {
+            if ( second == null ) {
+                return null;
+            }
+            return second;
+        }
+
+        if ( second == null ) {
+            return first;
+        }
+
+        if ( compare( first, second ) < 0 ) {
+            return first;
+        }
+        return second;
+    }
+
+
+    /** Returns the minimum UUID */
+    public static UUID max( UUID first, UUID second ) {
+        if ( first == null ) {
+            if ( second == null ) {
+                return null;
+            }
+            return second;
+        }
+
+        if ( second == null ) {
+            return first;
+        }
+
+        if ( compare( first, second ) < 0 ) {
+            return second;
+        }
+        return first;
+    }
+
+
+    /** Returns a UUID that is -1 of the passed uuid, sorted by time uuid only */
+    public static UUID decrement( UUID uuid ) {
+        if ( !isTimeBased( uuid ) ) {
+            throw new IllegalArgumentException( "The uuid must be a time type" );
+        }
+
+
+        //timestamp is in the 60 bit timestamp
+        long timestamp = uuid.timestamp();
+        timestamp--;
+
+        if ( timestamp < 0 ) {
+            throw new IllegalArgumentException( "You must specify a time uuid with a timestamp > 0" );
+        }
+
+        //get our bytes, then set the smaller timestamp into it
+        byte[] uuidBytes = bytes( uuid );
+
+        setTime( uuidBytes, timestamp );
+
+        return uuid( uuidBytes );
+    }
+
+
+    public static boolean isTimeBased( UUID uuid ) {
+        if ( uuid == null ) {
+            return false;
+        }
+        return uuid.version() == 1;
+    }
+
+
+    public static long getTimestampInMillis( UUID uuid ) {
+        if ( uuid == null ) {
+            return 0;
+        }
+        long t = uuid.timestamp();
+        return ( t - KCLOCK_OFFSET ) / KCLOCK_MULTIPLIER_L;
+    }
+
+
+    public static long getTimestampInMicros( UUID uuid ) {
+        if ( uuid == null ) {
+            return 0;
+        }
+        long t = uuid.timestamp();
+        return ( t - KCLOCK_OFFSET ) / 10;
+    }
+
+
+    public static UUID tryGetUUID( String s ) {
+        if ( s == null ) {
+            return null;
+        }
+        if ( s.length() != 36 ) {
+            return null;
+        }
+        // 8-4-4-4-12
+        // 0-7,8,9-12,13,14-17,18,19-22,23,24-35
+        if ( s.charAt( 8 ) != '-' ) {
+            return null;
+        }
+        if ( s.charAt( 13 ) != '-' ) {
+            return null;
+        }
+        if ( s.charAt( 18 ) != '-' ) {
+            return null;
+        }
+        if ( s.charAt( 23 ) != '-' ) {
+            return null;
+        }
+        UUID uuid = null;
+        try {
+            uuid = UUID.fromString( s );
+        }
+        catch ( Exception e ) {
+            LOG.info( "Could not convert String {} into a UUID", s, e );
+        }
+        return uuid;
+    }
+
+
+    public static boolean isUUID( String s ) {
+        return tryGetUUID( s ) != null;
+    }
+
+
+    public static UUID tryExtractUUID( String s ) {
+        if ( s == null ) {
+            return null;
+        }
+        if ( s.length() < 36 ) {
+            return null;
+        }
+        return tryGetUUID( s.substring( 0, 36 ) );
+    }
+
+
+    public static UUID tryExtractUUID( String s, int offset ) {
+        if ( s == null ) {
+            return null;
+        }
+        if ( ( s.length() - offset ) < 36 ) {
+            return null;
+        }
+        return tryGetUUID( s.substring( offset, offset + 36 ) );
+    }
+
+
+    public static String toBase64( UUID id ) {
+        if ( id == null ) {
+            return null;
+        }
+        return encodeBase64URLSafeString( bytes( id ) );
+    }
+
+
+    public static UUID fromBase64( String str ) {
+        if ( str == null ) {
+            return null;
+        }
+        byte[] bytes = decodeBase64( str );
+        if ( bytes.length != 16 ) {
+            return null;
+        }
+        return uuid( bytes );
+    }
+
+
+    public static int compare( UUID u1, UUID u2 ) {
+        return UUIDComparator.staticCompare( u1, u2 );
+    }
+
+
+    public static List<UUID> sort( List<UUID> uuids ) {
+        Collections.sort( uuids, new UUIDComparator() );
+        return uuids;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/CollectionIT.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/CollectionIT.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/CollectionIT.java
index 0444daf..f8736de 100644
--- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/CollectionIT.java
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/CollectionIT.java
@@ -43,9 +43,9 @@ import org.apache.usergrid.persistence.model.entity.SimpleId;
 import org.apache.usergrid.persistence.model.field.StringField;
 import org.apache.usergrid.persistence.query.Query;
 import org.apache.usergrid.persistence.query.Results;
-import org.apache.usergrid.persistence.utils.JsonUtils;
-import static org.apache.usergrid.persistence.utils.MapUtils.hashMap;
-import org.apache.usergrid.persistence.utils.UUIDUtils;
+import org.apache.usergrid.utils.JsonUtils;
+import static org.apache.usergrid.utils.MapUtils.hashMap;
+import org.apache.usergrid.utils.UUIDUtils;
 import org.jukito.JukitoRunner;
 import org.jukito.UseModules;
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/75da9b8d/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoIT.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoIT.java b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoIT.java
index 056e027..3a08638 100644
--- a/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoIT.java
+++ b/stack/corepersistence/queryindex/src/test/java/org/apache/usergrid/persistence/index/impl/GeoIT.java
@@ -39,7 +39,7 @@ import org.apache.usergrid.persistence.query.EntityRef;
 import org.apache.usergrid.persistence.query.Query;
 import org.apache.usergrid.persistence.query.Results;
 import org.apache.usergrid.persistence.query.SimpleEntityRef;
-import org.apache.usergrid.persistence.utils.MapUtils;
+import org.apache.usergrid.utils.MapUtils;
 import org.jukito.JukitoRunner;
 import org.jukito.UseModules;
 import static org.junit.Assert.assertEquals;