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/01/28 23:21:40 UTC

[30/96] [abbrv] [partial] Change package namespace to org.apache.usergrid

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/OrderByIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/OrderByIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/OrderByIterator.java
new file mode 100644
index 0000000..183615a
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/OrderByIterator.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.commons.collections.comparators.ComparatorChain;
+import org.apache.usergrid.persistence.Entity;
+import org.apache.usergrid.persistence.EntityManager;
+import org.apache.usergrid.persistence.EntityPropertyComparator;
+import org.apache.usergrid.persistence.Query;
+import org.apache.usergrid.persistence.Query.SortPredicate;
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+import org.apache.usergrid.persistence.query.ir.QuerySlice;
+
+import me.prettyprint.cassandra.serializers.UUIDSerializer;
+
+
+/**
+ * 1) Take a result set iterator as the child 2) Iterate only over candidates and create a cursor from the candidates
+ *
+ * @author tnine
+ */
+
+public class OrderByIterator extends MergeIterator {
+
+    private static final UUIDSerializer UUID_SER = new UUIDSerializer();
+
+    private static final String NAME_UUID = "uuid";
+    private static final Logger logger = LoggerFactory.getLogger( OrderByIterator.class );
+    private final QuerySlice slice;
+    private final ResultIterator candidates;
+    private final ComparatorChain subSortCompare;
+    private final List<String> secondaryFields;
+    private final EntityManager em;
+
+    //our last result from in memory sorting
+    private SortedEntitySet entries;
+
+
+    /**
+     * @param pageSize
+     */
+    public OrderByIterator( QuerySlice slice, List<Query.SortPredicate> secondary, ResultIterator candidates,
+                            EntityManager em, int pageSize ) {
+        super( pageSize );
+        this.slice = slice;
+        this.em = em;
+        this.candidates = candidates;
+        this.subSortCompare = new ComparatorChain();
+        this.secondaryFields = new ArrayList<String>( 1 + secondary.size() );
+
+        //add the sort of the primary column
+        this.secondaryFields.add( slice.getPropertyName() );
+        this.subSortCompare
+                .addComparator( new EntityPropertyComparator( slice.getPropertyName(), slice.isReversed() ) );
+
+        for ( SortPredicate sort : secondary ) {
+            this.subSortCompare.addComparator( new EntityPropertyComparator( sort.getPropertyName(),
+                    sort.getDirection() == Query.SortDirection.DESCENDING ) );
+            this.secondaryFields.add( sort.getPropertyName() );
+        }
+
+        //do uuid sorting last, this way if all our previous sorts are equal, we'll have a reproducible sort order for
+        // paging
+        this.secondaryFields.add( NAME_UUID );
+        this.subSortCompare.addComparator( new EntityPropertyComparator( NAME_UUID, false ) );
+    }
+
+
+    @Override
+    protected Set<ScanColumn> advance() {
+
+        ByteBuffer cursor = slice.getCursor();
+
+        UUID minEntryId = null;
+
+        if ( cursor != null ) {
+            minEntryId = UUID_SER.fromByteBuffer( cursor );
+        }
+
+        entries = new SortedEntitySet( subSortCompare, em, secondaryFields, pageSize, minEntryId );
+
+        /**
+         *  keep looping through our peek iterator.  We need to inspect each forward page to ensure we have performed a
+         *  seek to the end of our primary range.  Otherwise we need to keep aggregating. I.E  if the value is a boolean
+         *  and we order by "true
+         *  asc, timestamp desc" we must load every entity that has the value "true" before sub sorting,
+         *  then drop all values that fall out of the sort.
+         */
+        while ( candidates.hasNext() ) {
+
+
+            for ( ScanColumn id : candidates.next() ) {
+                entries.add( id );
+            }
+
+            entries.load();
+        }
+
+
+        return entries.toIds();
+    }
+
+
+    @Override
+    protected void doReset() {
+        // no op
+    }
+
+
+    @Override
+    public void finalizeCursor( CursorCache cache, UUID lastValue ) {
+        int sliceHash = slice.hashCode();
+
+        ByteBuffer bytes = UUID_SER.toByteBuffer( lastValue );
+
+        if ( bytes == null ) {
+            return;
+        }
+
+        cache.setNextCursor( sliceHash, bytes );
+    }
+
+
+    /** A Sorted set with a max size. When a new entry is added, the max is removed */
+    public static final class SortedEntitySet extends TreeSet<Entity> {
+
+        private final int maxSize;
+        private final Map<UUID, ScanColumn> cursorVal = new HashMap<UUID, ScanColumn>();
+        private final EntityManager em;
+        private final List<String> fields;
+        private final Entity minEntity;
+        private final Comparator<Entity> comparator;
+
+
+        public SortedEntitySet( Comparator<Entity> comparator, EntityManager em, List<String> fields, int maxSize,
+                                UUID minEntityId ) {
+            super( comparator );
+            this.maxSize = maxSize;
+            this.em = em;
+            this.fields = fields;
+            this.comparator = comparator;
+            this.minEntity = getPartialEntity( minEntityId );
+        }
+
+
+        @Override
+        public boolean add( Entity entity ) {
+
+            // don't add this entity.  We get it in our scan range, but it's <= the minimum value that
+            //should be allowed in the result set
+            if ( minEntity != null && comparator.compare( entity, minEntity ) <= 0 ) {
+                return false;
+            }
+
+            boolean added = super.add( entity );
+
+            while ( size() > maxSize ) {
+                //remove our last element, we're over size
+                Entity e = this.pollLast();
+                //remove it from the cursors as well
+                cursorVal.remove( e.getUuid() );
+            }
+
+            return added;
+        }
+
+
+        /** add the id to be loaded, and the dynamiccomposite column that belongs with it */
+        public void add( ScanColumn col ) {
+            cursorVal.put( col.getUUID(), col );
+        }
+
+
+        private Entity getPartialEntity( UUID minEntityId ) {
+            List<Entity> entities;
+
+            try {
+                entities = em.getPartialEntities( Collections.singletonList( minEntityId ), fields );
+            }
+            catch ( Exception e ) {
+                logger.error( "Unable to load partial entities", e );
+                throw new RuntimeException( e );
+            }
+
+            if ( entities == null || entities.size() == 0 ) {
+                return null;
+            }
+
+            return entities.get( 0 );
+        }
+
+
+        public void load() {
+            try {
+                for ( Entity e : em.getPartialEntities( cursorVal.keySet(), fields ) ) {
+                    add( e );
+                }
+            }
+            catch ( Exception e ) {
+                logger.error( "Unable to load partial entities", e );
+                throw new RuntimeException( e );
+            }
+        }
+
+
+        /** Turn our sorted entities into a set of ids */
+        public Set<ScanColumn> toIds() {
+            Iterator<Entity> itr = iterator();
+
+            Set<ScanColumn> columns = new LinkedHashSet<ScanColumn>( this.size() );
+
+            while ( itr.hasNext() ) {
+
+                UUID id = itr.next().getUuid();
+
+                columns.add( cursorVal.get( id ) );
+            }
+
+            return columns;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultIterator.java
new file mode 100644
index 0000000..cde2bc8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultIterator.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+
+
+/**
+ * Interface for iterating slice results per node.  This is to be used to iterate and join or intersect values Each
+ * iterator element is a set.  Each set size is determined by the underlying implementation.  When no sets of uuids are
+ * left the iterator should fail the next statement.  Note that you should not rely on the returned set being exactly
+ * the same size as the specified page size.  Valid sets can be returned with size >= that of the set value in the
+ * underlying implementation
+ *
+ * @author tnine
+ */
+public interface ResultIterator extends Iterable<Set<ScanColumn>>, Iterator<Set<ScanColumn>> {
+
+
+    /** Reset this iterator to the start to begin iterating again */
+    public void reset();
+
+    /** Finalize the cursor for this results.  Pass in the uuid of the last entity loaded. */
+    public void finalizeCursor( CursorCache cache, UUID lastValue );
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoader.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoader.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoader.java
new file mode 100644
index 0000000..9d0c70c
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoader.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.util.List;
+
+import org.apache.usergrid.persistence.Results;
+
+
+/** @author tnine */
+public interface ResultsLoader {
+
+    /** Load results from the list of uuids.  Should return a Results entity where the query cursor can be set */
+    public Results getResults( List<ScanColumn> entityIds ) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoaderFactory.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoaderFactory.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoaderFactory.java
new file mode 100644
index 0000000..c1c5fbb
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoaderFactory.java
@@ -0,0 +1,21 @@
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import org.apache.usergrid.persistence.EntityManager;
+import org.apache.usergrid.persistence.Query;
+import org.apache.usergrid.persistence.Results;
+
+
+/**
+ *
+ * @author: tnine
+ *
+ */
+public interface ResultsLoaderFactory {
+
+    /**
+     * Get the results loaded that will load all Ids given the results level.  The original query and the entity manager
+     * may be needed to load these results
+     */
+    public ResultsLoader getResultsLoader( EntityManager em, Query query, Results.Level level );
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumn.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumn.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumn.java
new file mode 100644
index 0000000..91603c8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumn.java
@@ -0,0 +1,16 @@
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+
+/** An interface that represents a column */
+public interface ScanColumn {
+
+    /** Get the uuid from the column */
+    public UUID getUUID();
+
+    /** Get the cursor value of this column */
+    public ByteBuffer getCursorValue();
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumnTransformer.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumnTransformer.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumnTransformer.java
new file mode 100644
index 0000000..3102404
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumnTransformer.java
@@ -0,0 +1,23 @@
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+
+/** Simple utility to convert Scan Columns collections to lists */
+public class ScanColumnTransformer {
+
+    public static List<UUID> getIds( Collection<ScanColumn> cols ) {
+
+        List<UUID> ids = new ArrayList<UUID>( cols.size() );
+
+        for ( ScanColumn col : cols ) {
+            ids.add( col.getUUID() );
+        }
+
+        return ids;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java
new file mode 100644
index 0000000..68bc37a
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+import me.prettyprint.hector.api.beans.DynamicComposite;
+
+
+/**
+ * Parser for reading and writing secondary index composites
+ *
+ * @author tnine
+ */
+public class SecondaryIndexSliceParser implements SliceParser {
+
+
+    /* (non-Javadoc)
+     * @see org.apache.usergrid.persistence.query.ir.result.SliceParser#parse(java.nio.ByteBuffer)
+     */
+    @Override
+    public ScanColumn parse( ByteBuffer buff ) {
+        DynamicComposite composite = DynamicComposite.fromByteBuffer( buff.duplicate() );
+
+        return new SecondaryIndexColumn( ( UUID ) composite.get( 2 ), composite.get( 1 ), buff );
+    }
+
+
+    public static class SecondaryIndexColumn extends AbstractScanColumn {
+
+        private final Object value;
+
+
+        public SecondaryIndexColumn( UUID uuid, Object value, ByteBuffer buff ) {
+            super( uuid, buff );
+            this.value = value;
+        }
+
+
+        /** Get the value from the node */
+        public Object getValue() {
+            return this.value;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java
new file mode 100644
index 0000000..3829ad8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+import org.apache.usergrid.persistence.cassandra.index.IndexScanner;
+import org.apache.usergrid.persistence.exceptions.QueryIterationException;
+import org.apache.usergrid.persistence.query.ir.QuerySlice;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import me.prettyprint.hector.api.beans.HColumn;
+
+
+/**
+ * An iterator that will take all slices and order them correctly
+ *
+ * @author tnine
+ */
+public class SliceIterator implements ResultIterator {
+
+    private static final Logger logger = LoggerFactory.getLogger( SliceIterator.class );
+
+    private final LinkedHashMap<UUID, ScanColumn> cols;
+    private final QuerySlice slice;
+    private final SliceParser parser;
+    private final IndexScanner scanner;
+    private final int pageSize;
+    private final boolean skipFirst;
+
+    /**
+     * Pointer to the uuid set until it's returned
+     */
+    private Set<ScanColumn> lastResult;
+
+    /**
+     * The pointer to the last set of parsed columns
+     */
+    private Set<ScanColumn> parsedCols;
+
+    /**
+     * counter that's incremented as we load pages. If pages loaded = 1 when reset, we don't have to reload from cass
+     */
+    private int pagesLoaded = 0;
+
+    /**
+     * Pointer to the last column we parsed
+     */
+    private ScanColumn last;
+
+
+    /**
+     * @param scanner The scanner to use to read the cols
+     * @param slice The slice used in the scanner
+     * @param parser The parser for the scanner results
+     * @param skipFirst True if the first record should be skipped, used with cursors
+     */
+    public SliceIterator( QuerySlice slice, IndexScanner scanner, SliceParser parser, boolean skipFirst ) {
+        this.slice = slice;
+        this.parser = parser;
+        this.scanner = scanner;
+        this.skipFirst = skipFirst;
+        this.pageSize = scanner.getPageSize();
+        this.cols = new LinkedHashMap<UUID, ScanColumn>( this.pageSize );
+        this.parsedCols = new LinkedHashSet<ScanColumn>( this.pageSize );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Iterable#iterator()
+     */
+    @Override
+    public Iterator<Set<ScanColumn>> iterator() {
+        return this;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Iterator#hasNext()
+     */
+    @Override
+    public boolean hasNext() {
+        if ( lastResult == null ) {
+            return load();
+        }
+
+        return true;
+    }
+
+
+    private boolean load() {
+        if ( !scanner.hasNext() ) {
+            return false;
+        }
+
+        Iterator<HColumn<ByteBuffer, ByteBuffer>> results = scanner.next().iterator();
+
+        cols.clear();
+
+        /**
+         * Skip the first value, it's from the previous cursor
+         */
+        if ( skipFirst && pagesLoaded == 0 && results.hasNext() ) {
+            results.next();
+        }
+
+        parsedCols.clear();
+
+        while ( results.hasNext() ) {
+
+            ByteBuffer colName = results.next().getName().duplicate();
+
+            ScanColumn parsed = parser.parse( colName );
+
+            //skip this value, the parser has discarded it
+            if ( parsed == null ) {
+                continue;
+            }
+
+            last = parsed;
+            cols.put( parsed.getUUID(), parsed );
+            parsedCols.add( parsed );
+        }
+
+
+        pagesLoaded++;
+
+        lastResult = parsedCols;
+
+        return lastResult != null && lastResult.size() > 0;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Iterator#next()
+     */
+    @Override
+    public Set<ScanColumn> next() {
+        Set<ScanColumn> temp = lastResult;
+        lastResult = null;
+        return temp;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Iterator#remove()
+     */
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException( "Remove is not supported" );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.usergrid.persistence.query.ir.result.ResultIterator#reset()
+     */
+    @Override
+    public void reset() {
+        // Do nothing, we'll just return the first page again
+        if ( pagesLoaded == 1 ) {
+            lastResult = parsedCols;
+            return;
+        }
+        scanner.reset();
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.apache.usergrid.persistence.query.ir.result.ResultIterator#finalizeCursor()
+     */
+    @Override
+    public void finalizeCursor( CursorCache cache, UUID lastLoaded ) {
+        final int sliceHash = slice.hashCode();
+
+        ByteBuffer bytes = null;
+
+        ScanColumn col = cols.get( lastLoaded );
+
+
+        //the column came from the current page
+        if ( col != null ) {
+            bytes = col.getCursorValue();
+        }
+        else {
+
+            //check if we reached the end of our iterator.  If we did, set the last value into the cursor.  Otherwise
+            //this is a bug
+            if ( scanner.hasNext() ) {
+                logger.error(
+                        "An iterator attempted to access a slice that was not iterated over.  This will result in the" +
+                                " cursor construction failing" );
+                throw new QueryIterationException(
+                        "An iterator attempted to access a slice that was not iterated over.  This will result in the" +
+                                " cursor construction failing" );
+            }
+
+            final ByteBuffer sliceCursor = slice.getCursor();
+
+            //we've never loaded anything, just re-use the existing slice
+            if (last == null && sliceCursor != null ) {
+                bytes = sliceCursor;
+            }
+
+            //use the last column we loaded.  This way our scan returns nothing next time since start == finish
+            else if(last != null) {
+                bytes = last.getCursorValue();
+            }
+        }
+
+
+        if ( bytes == null ) {
+            return;
+        }
+
+        cache.setNextCursor( sliceHash, bytes );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceParser.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceParser.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceParser.java
new file mode 100644
index 0000000..6f45efb
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceParser.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * Interface to parse and compare range slices
+ *
+ * @author tnine
+ */
+public interface SliceParser {
+
+    /** Parse the slice and return it's parse type.  If null is returned, the column should be considered discarded */
+    public ScanColumn parse( ByteBuffer buff );
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/StaticIdIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/StaticIdIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/StaticIdIterator.java
new file mode 100644
index 0000000..10ee4b8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/StaticIdIterator.java
@@ -0,0 +1,66 @@
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+
+
+/** Simple iterator that just returns UUIDs that are set into it */
+public class StaticIdIterator implements ResultIterator {
+
+    private final Set<ScanColumn> ids;
+
+    private boolean returnedOnce = false;
+
+
+    /**
+     *
+     */
+    public StaticIdIterator( UUID id ) {
+        final ScanColumn col = new UUIDIndexSliceParser.UUIDColumn( id, ByteBuffer.allocate( 0 ) );
+
+        ids = Collections.singleton( col );
+    }
+
+
+    @Override
+    public void reset() {
+        //no op
+    }
+
+
+    @Override
+    public void finalizeCursor( CursorCache cache, UUID lastValue ) {
+        //no cursor, it's a static list
+    }
+
+
+    @Override
+    public Iterator<Set<ScanColumn>> iterator() {
+        return this;
+    }
+
+
+    @Override
+    public boolean hasNext() {
+        return !returnedOnce;
+    }
+
+
+    @Override
+    public Set<ScanColumn> next() {
+        returnedOnce = true;
+        return ids;
+    }
+
+
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException( "This iterator does not support remove" );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SubtractionIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SubtractionIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SubtractionIterator.java
new file mode 100644
index 0000000..8475756
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SubtractionIterator.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+
+import com.google.common.collect.Sets;
+
+
+/**
+ * Simple iterator to perform Unions
+ *
+ * @author tnine
+ */
+public class SubtractionIterator extends MergeIterator {
+
+    private ResultIterator keepIterator;
+    private ResultIterator subtractIterator;
+
+
+    public SubtractionIterator( int pageSize ) {
+        super( pageSize );
+    }
+
+
+    /** @param subtractIterator the subtractIterator to set */
+    public void setSubtractIterator( ResultIterator subtractIterator ) {
+        this.subtractIterator = subtractIterator;
+    }
+
+
+    /** @param keepIterator the keepIterator to set */
+    public void setKeepIterator( ResultIterator keepIterator ) {
+        this.keepIterator = keepIterator;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.usergrid.persistence.query.ir.result.ResultIterator#reset()
+     */
+    @Override
+    public void doReset() {
+        keepIterator.reset();
+        subtractIterator.reset();
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.usergrid.persistence.query.ir.result.MergeIterator#advance()
+     */
+    @Override
+    protected Set<ScanColumn> advance() {
+        if ( !keepIterator.hasNext() ) {
+            return null;
+        }
+
+        Set<ScanColumn> results = new LinkedHashSet<ScanColumn>( pageSize );
+
+        while ( keepIterator.hasNext() && results.size() < pageSize ) {
+
+            Set<ScanColumn> keepPage = keepIterator.next();
+
+            while ( subtractIterator.hasNext() && keepPage.size() > 0 ) {
+                keepPage = Sets.difference( keepPage, subtractIterator.next() );
+            }
+
+            subtractIterator.reset();
+
+            results.addAll( keepPage );
+        }
+
+        return results;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.usergrid.persistence.query.ir.result.ResultIterator#finalizeCursor(org.apache.usergrid.persistence.cassandra
+     * .CursorCache)
+     */
+    @Override
+    public void finalizeCursor( CursorCache cache, UUID lastLoaded ) {
+        //we can only keep a cursor on our keep result set, we must subtract from every page of keep when loading
+        // results
+        keepIterator.finalizeCursor( cache, lastLoaded );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java
new file mode 100644
index 0000000..fecbc24
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+import me.prettyprint.cassandra.serializers.UUIDSerializer;
+
+
+/**
+ * Parser for reading and writing secondary index composites
+ *
+ * @author tnine
+ */
+public class UUIDIndexSliceParser implements SliceParser {
+
+    private static final UUIDSerializer SERIALIZER = UUIDSerializer.get();
+
+
+    /* (non-Javadoc)
+     * @see org.apache.usergrid.persistence.query.ir.result.SliceParser#parse(java.nio.ByteBuffer)
+     */
+    @Override
+    public ScanColumn parse( ByteBuffer buff ) {
+        return new UUIDColumn( SERIALIZER.fromByteBuffer( buff.duplicate() ), buff );
+    }
+
+
+    public static class UUIDColumn extends AbstractScanColumn {
+
+        public UUIDColumn( UUID uuid, ByteBuffer buffer ) {
+            super( uuid, buffer );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java
new file mode 100644
index 0000000..9630eda
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+import org.apache.usergrid.utils.UUIDUtils;
+
+import me.prettyprint.cassandra.serializers.UUIDSerializer;
+
+
+/**
+ * Simple iterator to perform Unions
+ *
+ * @author tnine
+ */
+public class UnionIterator extends MultiIterator {
+
+    private static final ScanColumnComparator COMP = new ScanColumnComparator();
+
+    private static final UUIDSerializer UUID_SERIALIZER = UUIDSerializer.get();
+
+
+    private SortedColumnList list;
+
+    private final int id;
+
+
+    /**
+     * @param pageSize The page size to return
+     * @param id The id assigned to this node
+     * @param minUuid The minimum UUID to return
+     */
+    public UnionIterator( int pageSize, int id, ByteBuffer minUuid ) {
+        super( pageSize );
+
+        this.id = id;
+
+        UUID parseMinUuid = null;
+
+        if(minUuid != null)      {
+            parseMinUuid = UUID_SERIALIZER.fromByteBuffer( minUuid );
+        }
+
+        list = new SortedColumnList( pageSize, parseMinUuid );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.usergrid.persistence.query.ir.result.MergeIterator#advance()
+     */
+    @Override
+    protected Set<ScanColumn> advance() {
+
+        int size = iterators.size();
+
+        if ( size == 0 ) {
+            return null;
+        }
+
+
+        list.clear();
+
+        for ( ResultIterator itr : iterators ) {
+
+            while ( itr.hasNext() ) {
+                list.addAll( itr.next() );
+            }
+
+            itr.reset();
+        }
+
+        //mark us for the next page
+        list.mark();
+
+
+        return list.asSet();
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.apache.usergrid.persistence.query.ir.result.ResultIterator#finalizeCursor(
+     * org.apache.usergrid.persistence.cassandra.CursorCache)
+     */
+    @Override
+    public void finalizeCursor( CursorCache cache, UUID lastLoaded ) {
+
+        ByteBuffer buff = UUIDSerializer.get().toByteBuffer( lastLoaded );
+        cache.setNextCursor( id, buff );
+        //get our scan column and put them in the cache
+        //we finalize the cursor of the min
+    }
+
+
+    /**
+     * A Sorted Set with a max size. When a new entry is added, the max is removed.  You can mark the next "min" by
+     * calling the mark method.  Values > min are accepted.  Values > min and that are over size are discarded
+     */
+    public static final class SortedColumnList {
+
+        private static final ScanColumnComparator COMP = new ScanColumnComparator();
+
+        private final int maxSize;
+
+        private final List<ScanColumn> list;
+
+
+        private ScanColumn min;
+
+
+        public SortedColumnList( final int maxSize, final UUID minUuid ) {
+            //we need to allocate the extra space if required
+            this.list = new ArrayList<ScanColumn>( maxSize );
+            this.maxSize = maxSize;
+
+            if ( minUuid != null ) {
+                min = new AbstractScanColumn( minUuid, null ) {};
+            }
+        }
+
+
+        /**
+         * Add the column to this list
+         */
+        public void add( ScanColumn col ) {
+            //less than our min, don't add
+            if ( COMP.compare( min, col ) >= 0 ) {
+                return;
+            }
+
+            int index = Collections.binarySearch( this.list, col, COMP );
+
+            //already present
+            if ( index > -1 ) {
+                return;
+            }
+
+            index = ( index * -1 ) - 1;
+
+            //outside the renage
+            if ( index >= maxSize ) {
+                return;
+            }
+
+            this.list.add( index, col );
+
+            final int size = this.list.size();
+
+            if ( size > maxSize ) {
+                this.list.subList( maxSize, size ).clear();
+            }
+        }
+
+
+        /**
+         * Add all the elements to this list
+         */
+        public void addAll( final Collection<? extends ScanColumn> cols ) {
+            for ( ScanColumn col : cols ) {
+                add( col );
+            }
+        }
+
+
+        /**
+         * Returns a new list.  If no elements are present, returns null
+         */
+        public Set<ScanColumn> asSet() {
+            if ( this.list.size() == 0 ) {
+                return null;
+            }
+
+            return new LinkedHashSet<ScanColumn>( this.list );
+        }
+
+
+        /**
+         * Mark our last element in the tree as the max
+         */
+        public void mark() {
+
+            final int size = this.list.size();
+
+            //we don't have any elements in the list, and we've never set a min
+            if ( size == 0 ) {
+                return;
+            }
+
+            min = this.list.get( size - 1 );
+        }
+
+
+        /**
+         * Clear the list
+         */
+        public void clear() {
+            this.list.clear();
+        }
+    }
+
+
+    /**
+     * Simple comparator for comparing scan columns.  Orders them by time uuid
+     */
+    private static class ScanColumnComparator implements Comparator<ScanColumn> {
+
+        @Override
+        public int compare( final ScanColumn o1, final ScanColumn o2 ) {
+            if ( o1 == null ) {
+                if ( o2 == null ) {
+                    return 0;
+                }
+
+                return -1;
+            }
+
+            else if ( o2 == null ) {
+                return 1;
+            }
+
+            return UUIDUtils.compare( o1.getUUID(), o2.getUUID() );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/.gitignore
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/.gitignore b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/.gitignore
new file mode 100644
index 0000000..65eb766
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/.gitignore
@@ -0,0 +1,2 @@
+/QueryFilterLexer.java
+/QueryFilterParser.java

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/AndOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/AndOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/AndOperand.java
new file mode 100644
index 0000000..e4c82ed
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/AndOperand.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.PersistenceException;
+
+
+/** @author tnine */
+public class AndOperand extends BooleanOperand {
+
+    public AndOperand() {
+        super( new CommonToken( 0, "and" ) );
+    }
+
+
+    public AndOperand( Token t ) {
+        super( t );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+     * .query.tree.QueryVisitor)
+     */
+    @Override
+    public void visit( QueryVisitor visitor ) throws PersistenceException {
+        visitor.visit( this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanLiteral.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanLiteral.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanLiteral.java
new file mode 100644
index 0000000..e624e25
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanLiteral.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+
+
+/** @author tnine */
+public class BooleanLiteral extends Literal<Boolean> {
+
+    private boolean value;
+
+
+    /**
+     * @param t
+     */
+    protected BooleanLiteral( Token t ) {
+        super( t );
+        value = Boolean.valueOf( t.getText() );
+    }
+
+
+    /** The boolean literal */
+    public BooleanLiteral( boolean value ) {
+        super( new ClassicToken( 0, String.valueOf( value ) ) );
+        this.value = value;
+    }
+
+
+    public Boolean getValue() {
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanOperand.java
new file mode 100644
index 0000000..ecf5451
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanOperand.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+
+
+/**
+ * A base class for any equality expression.  Expressions must have a property and a value. Examples are >=, >, =, <,
+ * <=,
+ *
+ * @author tnine
+ */
+public abstract class BooleanOperand extends Operand {
+
+
+    /**
+     * @param property
+     * @param literal
+     */
+    public BooleanOperand( Token t ) {
+        super( t );
+    }
+
+
+    public Operand getLeft() {
+        return ( Operand ) this.children.get( 0 );
+    }
+
+
+    public Operand getRight() {
+        return ( Operand ) this.children.get( 1 );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsOperand.java
new file mode 100644
index 0000000..aa75a1e
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsOperand.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.PersistenceException;
+
+
+/** @author tnine */
+public class ContainsOperand extends EqualityOperand {
+
+    /**
+     * @param property
+     * @param literal
+     */
+    public ContainsOperand( Token t ) {
+        super( t );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+     * .query.tree.QueryVisitor)
+     */
+    @Override
+    public void visit( QueryVisitor visitor ) throws PersistenceException {
+        visitor.visit( this );
+    }
+
+
+    public StringLiteral getString() {
+        return ( StringLiteral ) getLiteral();
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.usergrid.persistence.query.tree.EqualityOperand#newProperty(java.lang.String)
+     */
+    @Override
+    protected Property newProperty( String name ) {
+        return new ContainsProperty( name );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.usergrid.persistence.query.tree.EqualityOperand#getProperty()
+     */
+    @Override
+    public ContainsProperty getProperty() {
+        return ( ContainsProperty ) this.children.get( 0 );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsProperty.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsProperty.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsProperty.java
new file mode 100644
index 0000000..1e35af6
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsProperty.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+
+
+/**
+ * A property for full text searching that requires special renaming
+ *
+ * @author tnine
+ */
+public class ContainsProperty extends Property {
+
+    private String indexedName = null;
+
+
+    public ContainsProperty( Token t ) {
+        super( t );
+        this.indexedName = String.format( "%s.keywords", super.getValue() );
+    }
+
+
+    public ContainsProperty( String property ) {
+        this( new ClassicToken( 0, property ) );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.usergrid.persistence.query.tree.Property#getIndexedValue()
+     */
+    @Override
+    public String getIndexedValue() {
+        return this.indexedName;
+    }
+
+
+    /** @return the property */
+    public ContainsProperty getProperty() {
+        return ( ContainsProperty ) this.children.get( 0 );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Equal.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Equal.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Equal.java
new file mode 100644
index 0000000..d4d4406
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Equal.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.NoIndexException;
+
+
+/** @author tnine */
+public class Equal extends EqualityOperand {
+
+    /**
+     * @param property
+     * @param literal
+     */
+    public Equal( Token t ) {
+        super( t );
+    }
+
+
+    public Equal() {
+        super( new ClassicToken( 0, "=" ) );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+     * .query.tree.QueryVisitor)
+     */
+    @Override
+    public void visit( QueryVisitor visitor ) throws NoIndexException {
+        visitor.visit( this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/EqualityOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/EqualityOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/EqualityOperand.java
new file mode 100644
index 0000000..1e3cbc9
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/EqualityOperand.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+
+
+/**
+ * A base class for any equality expression. Expressions must have a property and a value. Examples are >=, >, =, <,
+ * <=,
+ *
+ * @author tnine
+ */
+public abstract class EqualityOperand extends Operand {
+
+    /**
+     * @param property
+     * @param literal
+     */
+    public EqualityOperand( Token t ) {
+        super( t );
+    }
+
+
+    public EqualityOperand( String propName, Literal<?> value ) {
+        super( null );
+    }
+
+
+    /** Set the property on this operand */
+    public void setProperty( String name ) {
+        setAtIndex( 0, newProperty( name ) );
+    }
+
+
+    /** Get the property to set into the equality. Allows subclasses to override the type */
+    protected Property newProperty( String name ) {
+        return new Property( name );
+    }
+
+
+    /** Set the literal on this operand from the given value */
+    public void setLiteral( Object value ) {
+        setAtIndex( 1, LiteralFactory.getLiteral( value ) );
+    }
+
+
+    /** Set the child at the specified index. If it doesn't exist, it's added until it does */
+    @SuppressWarnings("unchecked")
+    private void setAtIndex( int index, Literal<?> value ) {
+
+        if ( children == null ) {
+            children = createChildrenList();
+        }
+
+        while ( children.size() - 1 < index ) {
+            children.add( null );
+        }
+
+        setChild( index, value );
+    }
+
+
+    /** @return the property */
+    public Property getProperty() {
+        return ( Property ) this.children.get( 0 );
+    }
+
+
+    /** @return the literal */
+    public Literal<?> getLiteral() {
+        return ( Literal<?> ) this.children.get( 1 );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/FloatLiteral.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/FloatLiteral.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/FloatLiteral.java
new file mode 100644
index 0000000..6363234
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/FloatLiteral.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+
+
+/** @author tnine */
+public class FloatLiteral extends Literal<Float> implements NumericLiteral {
+
+    private float value;
+
+
+    /**
+     * @param t
+     */
+    public FloatLiteral( Token t ) {
+        super( t );
+        value = Float.valueOf( t.getText() );
+    }
+
+
+    public FloatLiteral( float f ) {
+        super( new ClassicToken( 0, String.valueOf( f ) ) );
+        value = f;
+    }
+
+
+    /** @return the value */
+    public Float getValue() {
+        return value;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.usergrid.persistence.query.tree.NumericLiteral#getFloatValue()
+     */
+    @Override
+    public float getFloatValue() {
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThan.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThan.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThan.java
new file mode 100644
index 0000000..0f6495f
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThan.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.NoIndexException;
+
+
+/** @author tnine */
+public class GreaterThan extends EqualityOperand {
+
+    /**
+     * @param property
+     * @param literal
+     */
+    public GreaterThan( Token t ) {
+        super( t );
+    }
+
+
+    public GreaterThan() {
+        super( new CommonToken( 0, ">" ) );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+     * .query.tree.QueryVisitor)
+     */
+    @Override
+    public void visit( QueryVisitor visitor ) throws NoIndexException {
+        visitor.visit( this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThanEqual.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThanEqual.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThanEqual.java
new file mode 100644
index 0000000..5d5d431
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThanEqual.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.NoIndexException;
+
+
+/** @author tnine */
+public class GreaterThanEqual extends EqualityOperand {
+
+    /**
+     * @param property
+     * @param literal
+     */
+    public GreaterThanEqual( Token t ) {
+        super( t );
+    }
+
+
+    /**
+     * @param property
+     * @param literal
+     */
+    public GreaterThanEqual() {
+        super( new CommonToken( 0, ">=" ) );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+     * .query.tree.QueryVisitor)
+     */
+    @Override
+    public void visit( QueryVisitor visitor ) throws NoIndexException {
+        visitor.visit( this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThan.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThan.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThan.java
new file mode 100644
index 0000000..a3c7979
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThan.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.NoIndexException;
+
+
+/** @author tnine */
+public class LessThan extends EqualityOperand {
+
+    /**
+     * @param property
+     * @param literal
+     */
+    public LessThan( Token t ) {
+        super( t );
+    }
+
+
+    public LessThan() {
+        super( new CommonToken( 0, "<" ) );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+     * .query.tree.QueryVisitor)
+     */
+    @Override
+    public void visit( QueryVisitor visitor ) throws NoIndexException {
+        visitor.visit( this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThanEqual.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThanEqual.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThanEqual.java
new file mode 100644
index 0000000..7638721
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThanEqual.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.NoIndexException;
+
+
+/** @author tnine */
+public class LessThanEqual extends EqualityOperand {
+
+    /**
+     * @param property
+     * @param literal
+     */
+    public LessThanEqual( Token t ) {
+        super( t );
+    }
+
+
+    /**
+     */
+    public LessThanEqual() {
+        super( new CommonToken( 0, "<=" ) );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+     * .query.tree.QueryVisitor)
+     */
+    @Override
+    public void visit( QueryVisitor visitor ) throws NoIndexException {
+        visitor.visit( this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Literal.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Literal.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Literal.java
new file mode 100644
index 0000000..60071c4
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Literal.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+import org.antlr.runtime.tree.CommonTree;
+
+
+/**
+ * Abstract class for literals
+ *
+ * @author tnine
+ */
+public abstract class Literal<V> extends CommonTree {
+
+
+    protected Literal( Token t ) {
+        super( t );
+    }
+
+
+    /** Return the value of the literal the user has passed in */
+    public abstract V getValue();
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LiteralFactory.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LiteralFactory.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LiteralFactory.java
new file mode 100644
index 0000000..cc69f9d
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LiteralFactory.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import java.util.UUID;
+
+
+/**
+ * Simple factory for generating literal instance based on the runtime value
+ *
+ * @author tnine
+ */
+public class LiteralFactory {
+
+    /** Generate the correct literal subclass based on the runtime instance. */
+    public static final Literal<?> getLiteral( Object value ) {
+        if ( value instanceof Integer ) {
+            return new LongLiteral( ( Integer ) value );
+        }
+        if ( value instanceof Long ) {
+            return new LongLiteral( ( Long ) value );
+        }
+
+        if ( value instanceof String ) {
+            return new StringLiteral( ( String ) value );
+        }
+
+        if ( value instanceof Float ) {
+            return new FloatLiteral( ( Float ) value );
+        }
+
+        if ( value instanceof UUID ) {
+            return new UUIDLiteral( ( UUID ) value );
+        }
+
+        if ( value instanceof Boolean ) {
+            return new BooleanLiteral( ( Boolean ) value );
+        }
+
+        throw new UnsupportedOperationException(
+                String.format( "Unsupported type of %s was passed when trying to construct a literal",
+                        value.getClass() ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LongLiteral.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LongLiteral.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LongLiteral.java
new file mode 100644
index 0000000..8f1b084
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LongLiteral.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+
+
+/** @author tnine */
+public class LongLiteral extends Literal<Long> implements NumericLiteral {
+
+    private long value;
+
+
+    /**
+     * @param t
+     */
+    public LongLiteral( Token t ) {
+        super( t );
+        this.value = Long.valueOf( t.getText() );
+    }
+
+
+    /**
+     *
+     * @param value
+     */
+    public LongLiteral( long value ) {
+        super( new ClassicToken( 0, String.valueOf( value ) ) );
+        this.value = value;
+    }
+
+
+    /**
+     *
+     * @return
+     */
+    public Long getValue() {
+        return this.value;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.usergrid.persistence.query.tree.NumericLiteral#getFloatValue()
+     */
+    @Override
+    public float getFloatValue() {
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NotOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NotOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NotOperand.java
new file mode 100644
index 0000000..8388e5d
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NotOperand.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.PersistenceException;
+
+
+/** @author tnine */
+public class NotOperand extends Operand {
+
+
+    public NotOperand( Token t ) {
+        super( t );
+    }
+
+
+    /** get the only child operation */
+    public Operand getOperation() {
+        return ( Operand ) this.children.get( 0 );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence.query.tree.QueryVisitor)
+     */
+    @Override
+    public void visit( QueryVisitor visitor ) throws PersistenceException {
+        visitor.visit( this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NumericLiteral.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NumericLiteral.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NumericLiteral.java
new file mode 100644
index 0000000..96d5f49
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NumericLiteral.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+/** @author tnine */
+public interface NumericLiteral {
+
+    /** Return the value of this numeric literal as a float */
+    public float getFloatValue();
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Operand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Operand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Operand.java
new file mode 100644
index 0000000..0f59ca8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Operand.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+import org.antlr.runtime.tree.CommonTree;
+import org.apache.usergrid.persistence.exceptions.PersistenceException;
+
+
+/**
+ * Any logical operation should subclass.  Boolean logic, equality, not, contains, within and others are examples of
+ * operands
+ *
+ * @author tnine
+ */
+public abstract class Operand extends CommonTree {
+
+
+    /** Default constructor to take a token */
+    public Operand( Token t ) {
+        super( t );
+    }
+
+
+    /** Get the pointer to the parent node */
+    public Operand getParent() {
+        return ( Operand ) super.getParent();
+    }
+
+
+    /** Visitor method */
+    public abstract void visit( QueryVisitor visitor ) throws PersistenceException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/OrOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/OrOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/OrOperand.java
new file mode 100644
index 0000000..1771dbc
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/OrOperand.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.PersistenceException;
+
+
+/** @author tnine */
+public class OrOperand extends BooleanOperand {
+
+    /**
+     * @param left
+     * @param token
+     * @param right
+     */
+    public OrOperand( Token t ) {
+        super( t );
+    }
+
+
+    public OrOperand() {
+        super( new CommonToken( 0, "or" ) );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+     * .query.tree.QueryVisitor)
+     */
+    @Override
+    public void visit( QueryVisitor visitor ) throws PersistenceException {
+        visitor.visit( this );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Property.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Property.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Property.java
new file mode 100644
index 0000000..36028c8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Property.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+
+
+/**
+ * A property
+ *
+ * @author tnine
+ */
+public class Property extends Literal<String> {
+
+    private String property;
+
+
+    public Property( Token t ) {
+        super( t );
+        this.property = t.getText();
+    }
+
+
+    public Property( String property ) {
+        this( new ClassicToken( 0, property ) );
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.usergrid.persistence.query.tree.Literal#getValue()
+     */
+    @Override
+    public String getValue() {
+        return this.property;
+    }
+
+
+    /**
+     * Subclasses an override.  Indexed value could be different when stored internally.  By default returns the same
+     * property
+     */
+    public String getIndexedValue() {
+        return this.property;
+    }
+}