http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/92ddfa59/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/QueryParserTokenManager.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/QueryParserTokenManager.java
 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/QueryParserTokenManager.java
new file mode 100644
index 0000000..68409cc
--- /dev/null
+++ 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/QueryParserTokenManager.java
@@ -0,0 +1,508 @@
+/* Generated By:JJTree&JavaCC: Do not edit this line. 
QueryParserTokenManager.java */
+package mvm.rya.indexing.accumulo.freetext.query;
+
+/*
+ * #%L
+ * mvm.rya.indexing.accumulo
+ * %%
+ * Copyright (C) 2014 Rya
+ * %%
+ * 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.
+ * #L%
+ */
+import java.io.StringReader;
+
+/** Token Manager. */
+public class QueryParserTokenManager implements QueryParserConstants
+{
+
+  /** Debug output. */
+  public  java.io.PrintStream debugStream = System.out;
+  /** Set debug output. */
+  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
+private final int jjStopStringLiteralDfa_0(int pos, long active0)
+{
+   switch (pos)
+   {
+      default :
+         return -1;
+   }
+}
+private final int jjStartNfa_0(int pos, long active0)
+{
+   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
+}
+private int jjStopAtPos(int pos, int kind)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   return pos + 1;
+}
+private int jjMoveStringLiteralDfa0_0()
+{
+   switch(curChar)
+   {
+      case 40:
+         return jjStopAtPos(0, 8);
+      case 41:
+         return jjStopAtPos(0, 9);
+      default :
+         return jjMoveNfa_0(2, 0);
+   }
+}
+static final long[] jjbitVec0 = {
+   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+private int jjMoveNfa_0(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 24;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 2:
+                  if ((0xfffff8fcffffd9ffL & l) != 0L)
+                  {
+                     if (kind > 12)
+                        kind = 12;
+                     jjCheckNAddStates(0, 2);
+                  }
+                  else if (curChar == 42)
+                     jjCheckNAdd(19);
+                  else if (curChar == 33)
+                  {
+                     if (kind > 7)
+                        kind = 7;
+                  }
+                  if (curChar == 34)
+                     jjCheckNAddTwoStates(16, 17);
+                  else if (curChar == 38)
+                  {
+                     if (kind > 5)
+                        kind = 5;
+                  }
+                  if (curChar == 38)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  break;
+               case 3:
+                  if (curChar == 38 && kind > 5)
+                     kind = 5;
+                  break;
+               case 4:
+                  if (curChar == 38)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  break;
+               case 5:
+                  if (curChar == 38 && kind > 5)
+                     kind = 5;
+                  break;
+               case 14:
+                  if (curChar == 33 && kind > 7)
+                     kind = 7;
+                  break;
+               case 15:
+                  if (curChar == 34)
+                     jjCheckNAddTwoStates(16, 17);
+                  break;
+               case 16:
+                  if ((0xfffffffbffffffffL & l) != 0L)
+                     jjCheckNAddTwoStates(16, 17);
+                  break;
+               case 17:
+                  if (curChar == 34 && kind > 10)
+                     kind = 10;
+                  break;
+               case 18:
+                  if (curChar == 42)
+                     jjCheckNAdd(19);
+                  break;
+               case 19:
+                  if ((0xfffff8fcffffd9ffL & l) == 0L)
+                     break;
+                  if (kind > 13)
+                     kind = 13;
+                  jjCheckNAdd(19);
+                  break;
+               case 20:
+                  if ((0xfffff8fcffffd9ffL & l) == 0L)
+                     break;
+                  if (kind > 12)
+                     kind = 12;
+                  jjCheckNAddStates(0, 2);
+                  break;
+               case 21:
+                  if ((0xfffff8fcffffd9ffL & l) == 0L)
+                     break;
+                  if (kind > 12)
+                     kind = 12;
+                  jjCheckNAdd(21);
+                  break;
+               case 22:
+                  if ((0xfffff8fcffffd9ffL & l) != 0L)
+                     jjCheckNAddTwoStates(22, 23);
+                  break;
+               case 23:
+                  if (curChar == 42 && kind > 14)
+                     kind = 14;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 2:
+                  if (kind > 12)
+                     kind = 12;
+                  jjCheckNAddStates(0, 2);
+                  if ((0x400000004000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 12;
+                  else if ((0x800000008000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 6;
+                  else if ((0x200000002L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 1;
+                  else if (curChar == 124)
+                  {
+                     if (kind > 6)
+                        kind = 6;
+                  }
+                  if (curChar == 124)
+                     jjstateSet[jjnewStateCnt++] = 8;
+                  break;
+               case 0:
+                  if ((0x1000000010L & l) != 0L && kind > 5)
+                     kind = 5;
+                  break;
+               case 1:
+                  if ((0x400000004000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 0;
+                  break;
+               case 6:
+                  if ((0x4000000040000L & l) != 0L && kind > 6)
+                     kind = 6;
+                  break;
+               case 7:
+                  if ((0x800000008000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 6;
+                  break;
+               case 8:
+                  if (curChar == 124 && kind > 6)
+                     kind = 6;
+                  break;
+               case 9:
+                  if (curChar == 124)
+                     jjstateSet[jjnewStateCnt++] = 8;
+                  break;
+               case 10:
+                  if (curChar == 124 && kind > 6)
+                     kind = 6;
+                  break;
+               case 11:
+                  if ((0x10000000100000L & l) != 0L && kind > 7)
+                     kind = 7;
+                  break;
+               case 12:
+                  if ((0x800000008000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 11;
+                  break;
+               case 13:
+                  if ((0x400000004000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 12;
+                  break;
+               case 16:
+                  jjAddStates(3, 4);
+                  break;
+               case 19:
+                  if (kind > 13)
+                     kind = 13;
+                  jjstateSet[jjnewStateCnt++] = 19;
+                  break;
+               case 20:
+                  if (kind > 12)
+                     kind = 12;
+                  jjCheckNAddStates(0, 2);
+                  break;
+               case 21:
+                  if (kind > 12)
+                     kind = 12;
+                  jjCheckNAdd(21);
+                  break;
+               case 22:
+                  jjCheckNAddTwoStates(22, 23);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 2:
+                  if ((jjbitVec0[i2] & l2) == 0L)
+                     break;
+                  if (kind > 12)
+                     kind = 12;
+                  jjCheckNAddStates(0, 2);
+                  break;
+               case 16:
+                  if ((jjbitVec0[i2] & l2) != 0L)
+                     jjAddStates(3, 4);
+                  break;
+               case 19:
+                  if ((jjbitVec0[i2] & l2) == 0L)
+                     break;
+                  if (kind > 13)
+                     kind = 13;
+                  jjstateSet[jjnewStateCnt++] = 19;
+                  break;
+               case 21:
+                  if ((jjbitVec0[i2] & l2) == 0L)
+                     break;
+                  if (kind > 12)
+                     kind = 12;
+                  jjCheckNAdd(21);
+                  break;
+               case 22:
+                  if ((jjbitVec0[i2] & l2) != 0L)
+                     jjCheckNAddTwoStates(22, 23);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 24 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+static final int[] jjnextStates = {
+   21, 22, 23, 16, 17, 
+};
+
+/** Token literal values. */
+public static final String[] jjstrLiteralImages = {
+"", null, null, null, null, null, null, null, "\50", "\51", null, null, null, 
+null, null, null, };
+
+/** Lexer state names. */
+public static final String[] lexStateNames = {
+   "DEFAULT",
+};
+static final long[] jjtoToken = {
+   0x77e1L, 
+};
+static final long[] jjtoSkip = {
+   0x1eL, 
+};
+protected SimpleCharStream input_stream;
+private final int[] jjrounds = new int[24];
+private final int[] jjstateSet = new int[48];
+protected char curChar;
+/** Constructor. */
+public QueryParserTokenManager(SimpleCharStream stream){
+   if (SimpleCharStream.staticFlag)
+      throw new Error("ERROR: Cannot use a static CharStream class with a 
non-static lexical analyzer.");
+   input_stream = stream;
+}
+
+/** Constructor. */
+public QueryParserTokenManager(SimpleCharStream stream, int lexState){
+   this(stream);
+   SwitchTo(lexState);
+}
+
+/** Reinitialise parser. */
+public void ReInit(SimpleCharStream stream)
+{
+   jjmatchedPos = jjnewStateCnt = 0;
+   curLexState = defaultLexState;
+   input_stream = stream;
+   ReInitRounds();
+}
+private void ReInitRounds()
+{
+   int i;
+   jjround = 0x80000001;
+   for (i = 24; i-- > 0;)
+      jjrounds[i] = 0x80000000;
+}
+
+/** Reinitialise parser. */
+public void ReInit(SimpleCharStream stream, int lexState)
+{
+   ReInit(stream);
+   SwitchTo(lexState);
+}
+
+/** Switch to specified lex state. */
+public void SwitchTo(int lexState)
+{
+   if (lexState >= 1 || lexState < 0)
+      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + 
lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+   else
+      curLexState = lexState;
+}
+
+protected Token jjFillToken()
+{
+   final Token t;
+   final String curTokenImage;
+   final int beginLine;
+   final int endLine;
+   final int beginColumn;
+   final int endColumn;
+   String im = jjstrLiteralImages[jjmatchedKind];
+   curTokenImage = (im == null) ? input_stream.GetImage() : im;
+   beginLine = input_stream.getBeginLine();
+   beginColumn = input_stream.getBeginColumn();
+   endLine = input_stream.getEndLine();
+   endColumn = input_stream.getEndColumn();
+   t = Token.newToken(jjmatchedKind, curTokenImage);
+
+   t.beginLine = beginLine;
+   t.endLine = endLine;
+   t.beginColumn = beginColumn;
+   t.endColumn = endColumn;
+
+   return t;
+}
+
+int curLexState = 0;
+int defaultLexState = 0;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
+
+/** Get the next Token. */
+public Token getNextToken() 
+{
+  Token matchedToken;
+  int curPos = 0;
+
+  EOFLoop :
+  for (;;)
+  {
+   try
+   {
+      curChar = input_stream.BeginToken();
+   }
+   catch(java.io.IOException e)
+   {
+      jjmatchedKind = 0;
+      matchedToken = jjFillToken();
+      return matchedToken;
+   }
+
+   try { input_stream.backup(0);
+      while (curChar <= 32 && (0x100002600L & (1L << curChar)) != 0L)
+         curChar = input_stream.BeginToken();
+   }
+   catch (java.io.IOException e1) { continue EOFLoop; }
+   jjmatchedKind = 0x7fffffff;
+   jjmatchedPos = 0;
+   curPos = jjMoveStringLiteralDfa0_0();
+   if (jjmatchedKind != 0x7fffffff)
+   {
+      if (jjmatchedPos + 1 < curPos)
+         input_stream.backup(curPos - jjmatchedPos - 1);
+      if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 
0L)
+      {
+         matchedToken = jjFillToken();
+         return matchedToken;
+      }
+      else
+      {
+         continue EOFLoop;
+      }
+   }
+   int error_line = input_stream.getEndLine();
+   int error_column = input_stream.getEndColumn();
+   String error_after = null;
+   boolean EOFSeen = false;
+   try { input_stream.readChar(); input_stream.backup(1); }
+   catch (java.io.IOException e1) {
+      EOFSeen = true;
+      error_after = curPos <= 1 ? "" : input_stream.GetImage();
+      if (curChar == '\n' || curChar == '\r') {
+         error_line++;
+         error_column = 0;
+      }
+      else
+         error_column++;
+   }
+   if (!EOFSeen) {
+      input_stream.backup(1);
+      error_after = curPos <= 1 ? "" : input_stream.GetImage();
+   }
+   throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, 
error_after, curChar, TokenMgrError.LEXICAL_ERROR);
+  }
+}
+
+private void jjCheckNAdd(int state)
+{
+   if (jjrounds[state] != jjround)
+   {
+      jjstateSet[jjnewStateCnt++] = state;
+      jjrounds[state] = jjround;
+   }
+}
+private void jjAddStates(int start, int end)
+{
+   do {
+      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+   } while (start++ != end);
+}
+private void jjCheckNAddTwoStates(int state1, int state2)
+{
+   jjCheckNAdd(state1);
+   jjCheckNAdd(state2);
+}
+
+private void jjCheckNAddStates(int start, int end)
+{
+   do {
+      jjCheckNAdd(jjnextStates[start]);
+   } while (start++ != end);
+}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/92ddfa59/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/QueryParserTreeConstants.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/QueryParserTreeConstants.java
 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/QueryParserTreeConstants.java
new file mode 100644
index 0000000..ca16e86
--- /dev/null
+++ 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/QueryParserTreeConstants.java
@@ -0,0 +1,39 @@
+/* Generated By:JavaCC: Do not edit this line. QueryParserTreeConstants.java 
Version 5.0 */
+package mvm.rya.indexing.accumulo.freetext.query;
+
+/*
+ * #%L
+ * mvm.rya.indexing.accumulo
+ * %%
+ * Copyright (C) 2014 Rya
+ * %%
+ * 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.
+ * #L%
+ */
+
+public interface QueryParserTreeConstants
+{
+  public int JJTSIMPLENODE = 0;
+  public int JJTEXPRESSION = 1;
+  public int JJTVOID = 2;
+  public int JJTTERM = 3;
+
+
+  public String[] jjtNodeName = {
+    "SimpleNode",
+    "Expression",
+    "void",
+    "Term",
+  };
+}
+/* JavaCC - OriginalChecksum=7db3f19ae343b33492ca4cbb4cb236be (do not edit 
this line) */

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/92ddfa59/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/SimpleCharStream.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/SimpleCharStream.java
 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/SimpleCharStream.java
new file mode 100644
index 0000000..bb7d581
--- /dev/null
+++ 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/SimpleCharStream.java
@@ -0,0 +1,491 @@
+/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 
5.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+package mvm.rya.indexing.accumulo.freetext.query;
+
+/*
+ * #%L
+ * mvm.rya.indexing.accumulo
+ * %%
+ * Copyright (C) 2014 Rya
+ * %%
+ * 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.
+ * #L%
+ */
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (without unicode processing).
+ */
+
+public class SimpleCharStream
+{
+/** Whether parser is static. */
+  public static final boolean staticFlag = false;
+  int bufsize;
+  int available;
+  int tokenBegin;
+/** Position in buffer. */
+  public int bufpos = -1;
+  protected int bufline[];
+  protected int bufcolumn[];
+
+  protected int column = 0;
+  protected int line = 1;
+
+  protected boolean prevCharIsCR = false;
+  protected boolean prevCharIsLF = false;
+
+  protected java.io.Reader inputStream;
+
+  protected char[] buffer;
+  protected int maxNextCharInd = 0;
+  protected int inBuf = 0;
+  protected int tabSize = 8;
+
+  protected void setTabSize(int i) { tabSize = i; }
+  protected int getTabSize(int i) { return tabSize; }
+
+
+  protected void ExpandBuff(boolean wrapAround)
+  {
+    char[] newbuffer = new char[bufsize + 2048];
+    int newbufline[] = new int[bufsize + 2048];
+    int newbufcolumn[] = new int[bufsize + 2048];
+
+    try
+    {
+      if (wrapAround)
+      {
+        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - 
tokenBegin);
+        System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
+        buffer = newbuffer;
+
+        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - 
tokenBegin);
+        System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+        bufline = newbufline;
+
+        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - 
tokenBegin);
+        System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, 
bufpos);
+        bufcolumn = newbufcolumn;
+
+        maxNextCharInd = (bufpos += (bufsize - tokenBegin));
+      }
+      else
+      {
+        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - 
tokenBegin);
+        buffer = newbuffer;
+
+        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - 
tokenBegin);
+        bufline = newbufline;
+
+        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - 
tokenBegin);
+        bufcolumn = newbufcolumn;
+
+        maxNextCharInd = (bufpos -= tokenBegin);
+      }
+    }
+    catch (Throwable t)
+    {
+      throw new Error(t.getMessage());
+    }
+
+
+    bufsize += 2048;
+    available = bufsize;
+    tokenBegin = 0;
+  }
+
+  protected void FillBuff() throws java.io.IOException
+  {
+    if (maxNextCharInd == available)
+    {
+      if (available == bufsize)
+      {
+        if (tokenBegin > 2048)
+        {
+          bufpos = maxNextCharInd = 0;
+          available = tokenBegin;
+        }
+        else if (tokenBegin < 0)
+          bufpos = maxNextCharInd = 0;
+        else
+          ExpandBuff(false);
+      }
+      else if (available > tokenBegin)
+        available = bufsize;
+      else if ((tokenBegin - available) < 2048)
+        ExpandBuff(true);
+      else
+        available = tokenBegin;
+    }
+
+    int i;
+    try {
+      if ((i = inputStream.read(buffer, maxNextCharInd, available - 
maxNextCharInd)) == -1)
+      {
+        inputStream.close();
+        throw new java.io.IOException();
+      }
+      else
+        maxNextCharInd += i;
+      return;
+    }
+    catch(java.io.IOException e) {
+      --bufpos;
+      backup(0);
+      if (tokenBegin == -1)
+        tokenBegin = bufpos;
+      throw e;
+    }
+  }
+
+/** Start. */
+  public char BeginToken() throws java.io.IOException
+  {
+    tokenBegin = -1;
+    char c = readChar();
+    tokenBegin = bufpos;
+
+    return c;
+  }
+
+  protected void UpdateLineColumn(char c)
+  {
+    column++;
+
+    if (prevCharIsLF)
+    {
+      prevCharIsLF = false;
+      line += (column = 1);
+    }
+    else if (prevCharIsCR)
+    {
+      prevCharIsCR = false;
+      if (c == '\n')
+      {
+        prevCharIsLF = true;
+      }
+      else
+        line += (column = 1);
+    }
+
+    switch (c)
+    {
+      case '\r' :
+        prevCharIsCR = true;
+        break;
+      case '\n' :
+        prevCharIsLF = true;
+        break;
+      case '\t' :
+        column--;
+        column += (tabSize - (column % tabSize));
+        break;
+      default :
+        break;
+    }
+
+    bufline[bufpos] = line;
+    bufcolumn[bufpos] = column;
+  }
+
+/** Read a character. */
+  public char readChar() throws java.io.IOException
+  {
+    if (inBuf > 0)
+    {
+      --inBuf;
+
+      if (++bufpos == bufsize)
+        bufpos = 0;
+
+      return buffer[bufpos];
+    }
+
+    if (++bufpos >= maxNextCharInd)
+      FillBuff();
+
+    char c = buffer[bufpos];
+
+    UpdateLineColumn(c);
+    return c;
+  }
+
+  @Deprecated
+  /**
+   * @deprecated
+   * @see #getEndColumn
+   */
+
+  public int getColumn() {
+    return bufcolumn[bufpos];
+  }
+
+  @Deprecated
+  /**
+   * @deprecated
+   * @see #getEndLine
+   */
+
+  public int getLine() {
+    return bufline[bufpos];
+  }
+
+  /** Get token end column number. */
+  public int getEndColumn() {
+    return bufcolumn[bufpos];
+  }
+
+  /** Get token end line number. */
+  public int getEndLine() {
+     return bufline[bufpos];
+  }
+
+  /** Get token beginning column number. */
+  public int getBeginColumn() {
+    return bufcolumn[tokenBegin];
+  }
+
+  /** Get token beginning line number. */
+  public int getBeginLine() {
+    return bufline[tokenBegin];
+  }
+
+/** Backup a number of characters. */
+  public void backup(int amount) {
+
+    inBuf += amount;
+    if ((bufpos -= amount) < 0)
+      bufpos += bufsize;
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.Reader dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    available = bufsize = buffersize;
+    buffer = new char[buffersize];
+    bufline = new int[buffersize];
+    bufcolumn = new int[buffersize];
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.Reader dstream, int startline,
+                          int startcolumn)
+  {
+    this(dstream, startline, startcolumn, 4096);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.Reader dstream)
+  {
+    this(dstream, 1, 1, 4096);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.Reader dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    if (buffer == null || buffersize != buffer.length)
+    {
+      available = bufsize = buffersize;
+      buffer = new char[buffersize];
+      bufline = new int[buffersize];
+      bufcolumn = new int[buffersize];
+    }
+    prevCharIsLF = prevCharIsCR = false;
+    tokenBegin = inBuf = maxNextCharInd = 0;
+    bufpos = -1;
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.Reader dstream, int startline,
+                     int startcolumn)
+  {
+    ReInit(dstream, startline, startcolumn, 4096);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.Reader dstream)
+  {
+    ReInit(dstream, 1, 1, 4096);
+  }
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream, String encoding, int 
startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+    this(encoding == null ? new java.io.InputStreamReader(dstream) : new 
java.io.InputStreamReader(dstream, encoding), startline, startcolumn, 
buffersize);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    this(new java.io.InputStreamReader(dstream), startline, startcolumn, 
buffersize);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream, String encoding, int 
startline,
+                          int startcolumn) throws 
java.io.UnsupportedEncodingException
+  {
+    this(dstream, encoding, startline, startcolumn, 4096);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream, int startline,
+                          int startcolumn)
+  {
+    this(dstream, startline, startcolumn, 4096);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream, String encoding) throws 
java.io.UnsupportedEncodingException
+  {
+    this(dstream, encoding, 1, 1, 4096);
+  }
+
+  /** Constructor. */
+  public SimpleCharStream(java.io.InputStream dstream)
+  {
+    this(dstream, 1, 1, 4096);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, String encoding, int 
startline,
+                          int startcolumn, int buffersize) throws 
java.io.UnsupportedEncodingException
+  {
+    ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new 
java.io.InputStreamReader(dstream, encoding), startline, startcolumn, 
buffersize);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, int startline,
+                          int startcolumn, int buffersize)
+  {
+    ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 
buffersize);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, String encoding) throws 
java.io.UnsupportedEncodingException
+  {
+    ReInit(dstream, encoding, 1, 1, 4096);
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream)
+  {
+    ReInit(dstream, 1, 1, 4096);
+  }
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, String encoding, int 
startline,
+                     int startcolumn) throws 
java.io.UnsupportedEncodingException
+  {
+    ReInit(dstream, encoding, startline, startcolumn, 4096);
+  }
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, int startline,
+                     int startcolumn)
+  {
+    ReInit(dstream, startline, startcolumn, 4096);
+  }
+  /** Get token literal value. */
+  public String GetImage()
+  {
+    if (bufpos >= tokenBegin)
+      return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+    else
+      return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+                            new String(buffer, 0, bufpos + 1);
+  }
+
+  /** Get the suffix. */
+  public char[] GetSuffix(int len)
+  {
+    char[] ret = new char[len];
+
+    if ((bufpos + 1) >= len)
+      System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+    else
+    {
+      System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+                                                        len - bufpos - 1);
+      System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+    }
+
+    return ret;
+  }
+
+  /** Reset buffer when finished. */
+  public void Done()
+  {
+    buffer = null;
+    bufline = null;
+    bufcolumn = null;
+  }
+
+  /**
+   * Method to adjust line and column numbers for the start of a token.
+   */
+  public void adjustBeginLineColumn(int newLine, int newCol)
+  {
+    int start = tokenBegin;
+    int len;
+
+    if (bufpos >= tokenBegin)
+    {
+      len = bufpos - tokenBegin + inBuf + 1;
+    }
+    else
+    {
+      len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+    }
+
+    int i = 0, j = 0, k = 0;
+    int nextColDiff = 0, columnDiff = 0;
+
+    while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % 
bufsize])
+    {
+      bufline[j] = newLine;
+      nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+      bufcolumn[j] = newCol + columnDiff;
+      columnDiff = nextColDiff;
+      i++;
+    }
+
+    if (i < len)
+    {
+      bufline[j] = newLine++;
+      bufcolumn[j] = newCol + columnDiff;
+
+      while (i++ < len)
+      {
+        if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+          bufline[j] = newLine++;
+        else
+          bufline[j] = newLine;
+      }
+    }
+
+    line = bufline[j];
+    column = bufcolumn[j];
+  }
+
+}
+/* JavaCC - OriginalChecksum=003f6ea93d012999f2e1302d1daab102 (do not edit 
this line) */

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/92ddfa59/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/SimpleNode.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/SimpleNode.java
 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/SimpleNode.java
new file mode 100644
index 0000000..a530ddf
--- /dev/null
+++ 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/SimpleNode.java
@@ -0,0 +1,99 @@
+/* Generated By:JJTree: Do not edit this line. SimpleNode.java Version 4.3 */
+/* 
JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=false,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true
 */
+package mvm.rya.indexing.accumulo.freetext.query;
+
+/*
+ * #%L
+ * mvm.rya.indexing.accumulo
+ * %%
+ * Copyright (C) 2014 Rya
+ * %%
+ * 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.
+ * #L%
+ */
+
+public
+class SimpleNode implements Node {
+
+  protected Node parent;
+  protected Node[] children;
+  protected int id;
+  protected Object value;
+  protected QueryParser parser;
+
+  public SimpleNode(int i) {
+    id = i;
+  }
+
+  public SimpleNode(QueryParser p, int i) {
+    this(i);
+    parser = p;
+  }
+
+  public void jjtOpen() {
+  }
+
+  public void jjtClose() {
+  }
+
+  public void jjtSetParent(Node n) { parent = n; }
+  public Node jjtGetParent() { return parent; }
+
+  public void jjtAddChild(Node n, int i) {
+    if (children == null) {
+      children = new Node[i + 1];
+    } else if (i >= children.length) {
+      Node c[] = new Node[i + 1];
+      System.arraycopy(children, 0, c, 0, children.length);
+      children = c;
+    }
+    children[i] = n;
+  }
+
+  public Node jjtGetChild(int i) {
+    return children[i];
+  }
+
+  public int jjtGetNumChildren() {
+    return (children == null) ? 0 : children.length;
+  }
+
+  public void jjtSetValue(Object value) { this.value = value; }
+  public Object jjtGetValue() { return value; }
+
+  /* You can override these two methods in subclasses of SimpleNode to
+     customize the way the node appears when the tree is dumped.  If
+     your output uses more than one line you should override
+     toString(String), otherwise overriding toString() is probably all
+     you need to do. */
+
+  public String toString() { return QueryParserTreeConstants.jjtNodeName[id]; }
+  public String toString(String prefix) { return prefix + toString(); }
+
+  /* Override this method if you want to customize how the node dumps
+     out its children. */
+
+  public void dump(String prefix) {
+    System.out.println(toString(prefix));
+    if (children != null) {
+      for (int i = 0; i < children.length; ++i) {
+        SimpleNode n = (SimpleNode)children[i];
+        if (n != null) {
+          n.dump(prefix + " ");
+        }
+      }
+    }
+  }
+}
+
+/* JavaCC - OriginalChecksum=d65b3d27c1d9231908f90be143472875 (do not edit 
this line) */

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/92ddfa59/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/Token.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/Token.java
 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/Token.java
new file mode 100644
index 0000000..1ef8ec9
--- /dev/null
+++ 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/Token.java
@@ -0,0 +1,151 @@
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
+/* 
JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true
 */
+package mvm.rya.indexing.accumulo.freetext.query;
+
+/*
+ * #%L
+ * mvm.rya.indexing.accumulo
+ * %%
+ * Copyright (C) 2014 Rya
+ * %%
+ * 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.
+ * #L%
+ */
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token implements java.io.Serializable {
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * An integer that describes the kind of this token.  This numbering
+   * system is determined by JavaCCParser, and a table of these numbers is
+   * stored in the file ...Constants.java.
+   */
+  public int kind;
+
+  /** The line number of the first character of this Token. */
+  public int beginLine;
+  /** The column number of the first character of this Token. */
+  public int beginColumn;
+  /** The line number of the last character of this Token. */
+  public int endLine;
+  /** The column number of the last character of this Token. */
+  public int endColumn;
+
+  /**
+   * The string image of the token.
+   */
+  public String image;
+
+  /**
+   * A reference to the next regular (non-special) token from the input
+   * stream.  If this is the last token from the input stream, or if the
+   * token manager has not read tokens beyond this one, this field is
+   * set to null.  This is true only if this token is also a regular
+   * token.  Otherwise, see below for a description of the contents of
+   * this field.
+   */
+  public Token next;
+
+  /**
+   * This field is used to access special tokens that occur prior to this
+   * token, but after the immediately preceding regular (non-special) token.
+   * If there are no such special tokens, this field is set to null.
+   * When there are more than one such special token, this field refers
+   * to the last of these special tokens, which in turn refers to the next
+   * previous special token through its specialToken field, and so on
+   * until the first special token (whose specialToken field is null).
+   * The next fields of special tokens refer to other special tokens that
+   * immediately follow it (without an intervening regular token).  If there
+   * is no such token, this field is null.
+   */
+  public Token specialToken;
+
+  /**
+   * An optional attribute value of the Token.
+   * Tokens which are not used as syntactic sugar will often contain
+   * meaningful values that will be used later on by the compiler or
+   * interpreter. This attribute value is often different from the image.
+   * Any subclass of Token that actually wants to return a non-null value can
+   * override this method as appropriate.
+   */
+  public Object getValue() {
+    return null;
+  }
+
+  /**
+   * No-argument constructor
+   */
+  public Token() {}
+
+  /**
+   * Constructs a new token for the specified Image.
+   */
+  public Token(int kind)
+  {
+    this(kind, null);
+  }
+
+  /**
+   * Constructs a new token for the specified Image and Kind.
+   */
+  public Token(int kind, String image)
+  {
+    this.kind = kind;
+    this.image = image;
+  }
+
+  /**
+   * Returns the image.
+   */
+  public String toString()
+  {
+    return image;
+  }
+
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simply add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken(ofKind, image);
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use sit in your lexical actions.
+   */
+  public static Token newToken(int ofKind, String image)
+  {
+    switch(ofKind)
+    {
+      default : return new Token(ofKind, image);
+    }
+  }
+
+  public static Token newToken(int ofKind)
+  {
+    return newToken(ofKind, null);
+  }
+
+}
+/* JavaCC - OriginalChecksum=6e0a6d0b8d0fef396f67c3e7b1b29b5c (do not edit 
this line) */

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/92ddfa59/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/TokenMgrError.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/TokenMgrError.java
 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/TokenMgrError.java
new file mode 100644
index 0000000..f58542d
--- /dev/null
+++ 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/freetext/query/TokenMgrError.java
@@ -0,0 +1,167 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 
*/
+/* JavaCCOptions: */
+package mvm.rya.indexing.accumulo.freetext.query;
+
+/*
+ * #%L
+ * mvm.rya.indexing.accumulo
+ * %%
+ * Copyright (C) 2014 Rya
+ * %%
+ * 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.
+ * #L%
+ */
+
+/** Token Manager Error. */
+public class TokenMgrError extends Error
+{
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /*
+   * Ordinals for various reasons why an Error of this type can be thrown.
+   */
+
+  /**
+   * Lexical error occurred.
+   */
+  static final int LEXICAL_ERROR = 0;
+
+  /**
+   * An attempt was made to create a second instance of a static token manager.
+   */
+  static final int STATIC_LEXER_ERROR = 1;
+
+  /**
+   * Tried to change to an invalid lexical state.
+   */
+  static final int INVALID_LEXICAL_STATE = 2;
+
+  /**
+   * Detected (and bailed out of) an infinite loop in the token manager.
+   */
+  static final int LOOP_DETECTED = 3;
+
+  /**
+   * Indicates the reason why the exception is thrown. It will have
+   * one of the above 4 values.
+   */
+  int errorCode;
+
+  /**
+   * Replaces unprintable characters by their escaped (or unicode escaped)
+   * equivalents in the given string
+   */
+  protected static final String addEscapes(String str) {
+    StringBuffer retval = new StringBuffer();
+    char ch;
+    for (int i = 0; i < str.length(); i++) {
+      switch (str.charAt(i))
+      {
+        case 0 :
+          continue;
+        case '\b':
+          retval.append("\\b");
+          continue;
+        case '\t':
+          retval.append("\\t");
+          continue;
+        case '\n':
+          retval.append("\\n");
+          continue;
+        case '\f':
+          retval.append("\\f");
+          continue;
+        case '\r':
+          retval.append("\\r");
+          continue;
+        case '\"':
+          retval.append("\\\"");
+          continue;
+        case '\'':
+          retval.append("\\\'");
+          continue;
+        case '\\':
+          retval.append("\\\\");
+          continue;
+        default:
+          if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+            String s = "0000" + Integer.toString(ch, 16);
+            retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+          } else {
+            retval.append(ch);
+          }
+          continue;
+      }
+    }
+    return retval.toString();
+  }
+
+  /**
+   * Returns a detailed message for the Error when it is thrown by the
+   * token manager to indicate a lexical error.
+   * Parameters :
+   *    EOFSeen     : indicates if EOF caused the lexical error
+   *    curLexState : lexical state in which this error occurred
+   *    errorLine   : line number when the error occurred
+   *    errorColumn : column number when the error occurred
+   *    errorAfter  : prefix that was seen before this error occurred
+   *    curchar     : the offending character
+   * Note: You can customize the lexical error message by modifying this 
method.
+   */
+  protected static String LexicalError(boolean EOFSeen, int lexState, int 
errorLine, int errorColumn, String errorAfter, char curChar) {
+    return("Lexical error at line " +
+          errorLine + ", column " +
+          errorColumn + ".  Encountered: " +
+          (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + 
"\"") + " (" + (int)curChar + "), ") +
+          "after : \"" + addEscapes(errorAfter) + "\"");
+  }
+
+  /**
+   * You can also modify the body of this method to customize your error 
messages.
+   * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+   * of end-users concern, so you can return something like :
+   *
+   *     "Internal Error : Please file a bug report .... "
+   *
+   * from this method for such cases in the release version of your parser.
+   */
+  public String getMessage() {
+    return super.getMessage();
+  }
+
+  /*
+   * Constructors of various flavors follow.
+   */
+
+  /** No arg constructor. */
+  public TokenMgrError() {
+  }
+
+  /** Constructor with message and reason. */
+  public TokenMgrError(String message, int reason) {
+    super(message);
+    errorCode = reason;
+  }
+
+  /** Full Constructor. */
+  public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int 
errorColumn, String errorAfter, char curChar, int reason) {
+    this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, 
curChar), reason);
+  }
+}
+/* JavaCC - OriginalChecksum=290a4c5d743d0af7d70c6c0c9cd1d448 (do not edit 
this line) */

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/92ddfa59/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoConstants.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoConstants.java 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoConstants.java
new file mode 100644
index 0000000..350ccc6
--- /dev/null
+++ 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoConstants.java
@@ -0,0 +1,44 @@
+package mvm.rya.indexing.accumulo.geo;
+
+/*
+ * #%L
+ * mvm.rya.indexing.accumulo
+ * %%
+ * Copyright (C) 2014 Rya
+ * %%
+ * 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.
+ * #L%
+ */
+
+import org.openrdf.model.URI;
+import org.openrdf.model.impl.URIImpl;
+
+/**
+ * A set of URIs used in GeoSPARQL
+ */
+public class GeoConstants {
+       public static final String NS_GEO = 
"http://www.opengis.net/ont/geosparql#";;
+       public static final String NS_GEOF = 
"http://www.opengis.net/def/function/geosparql/";;
+
+       public static final URI XMLSCHEMA_OGC_WKT = new URIImpl(NS_GEO + 
"wktLiteral");
+       public static final URI GEO_AS_WKT = new URIImpl(NS_GEO + "asWKT");
+
+       public static final URI GEO_SF_EQUALS = new URIImpl(NS_GEOF + 
"sfEquals");
+       public static final URI GEO_SF_DISJOINT = new URIImpl(NS_GEOF + 
"sfDisjoint");
+       public static final URI GEO_SF_INTERSECTS = new URIImpl(NS_GEOF + 
"sfIntersects");
+       public static final URI GEO_SF_TOUCHES = new URIImpl(NS_GEOF + 
"sfTouches");
+       public static final URI GEO_SF_CROSSES = new URIImpl(NS_GEOF + 
"sfCrosses");
+       public static final URI GEO_SF_WITHIN = new URIImpl(NS_GEOF + 
"sfWithin");
+       public static final URI GEO_SF_CONTAINS = new URIImpl(NS_GEOF + 
"sfContains");
+       public static final URI GEO_SF_OVERLAPS = new URIImpl(NS_GEOF + 
"sfOverlaps");
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/92ddfa59/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java
 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java
new file mode 100644
index 0000000..e012a7f
--- /dev/null
+++ 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoMesaGeoIndexer.java
@@ -0,0 +1,446 @@
+package mvm.rya.indexing.accumulo.geo;
+
+/*
+ * #%L
+ * mvm.rya.indexing.accumulo
+ * %%
+ * Copyright (C) 2014 Rya
+ * %%
+ * 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.
+ * #L%
+ */
+
+import info.aduna.iteration.CloseableIteration;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import mvm.rya.accumulo.AccumuloRdfConfiguration;
+import mvm.rya.accumulo.experimental.AbstractAccumuloIndexer;
+import mvm.rya.accumulo.experimental.AccumuloIndexer;
+import mvm.rya.api.RdfCloudTripleStoreConfiguration;
+import mvm.rya.api.domain.RyaStatement;
+import mvm.rya.api.domain.RyaURI;
+import mvm.rya.api.resolver.RyaToRdfConversions;
+import mvm.rya.indexing.GeoIndexer;
+import mvm.rya.indexing.StatementContraints;
+import mvm.rya.indexing.accumulo.ConfigUtils;
+import mvm.rya.indexing.accumulo.Md5Hash;
+import mvm.rya.indexing.accumulo.StatementSerializer;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.MultiTableBatchWriter;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+import org.geotools.data.DataStore;
+import org.geotools.data.DataStoreFinder;
+import org.geotools.data.FeatureSource;
+import org.geotools.data.FeatureStore;
+import org.geotools.data.Query;
+import org.geotools.factory.Hints;
+import org.geotools.feature.DefaultFeatureCollection;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.filter.text.cql2.CQLException;
+import org.geotools.filter.text.ecql.ECQL;
+import org.locationtech.geomesa.accumulo.index.Constants;
+import org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.openrdf.model.Literal;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.query.QueryEvaluationException;
+
+import com.google.common.base.Preconditions;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+
+/**
+ * A {@link GeoIndexer} wrapper around a GeoMesa {@link AccumuloDataStore}. 
This class configures and connects to the Datastore, creates the
+ * RDF Feature Type, and interacts with the Datastore.
+ * <p>
+ * Specifically, this class creates a RDF Feature type and stores each RDF 
Statement as a RDF Feature in the datastore. Each feature
+ * contains the standard set of GeoMesa attributes (Geometry, Start Date, and 
End Date). The GeoMesaGeoIndexer populates the Geometry
+ * attribute by parsing the Well-Known Text contained in the RDF Statement’s 
object literal value.
+ * <p>
+ * The RDF Feature contains four additional attributes for each component of 
the RDF Statement. These attributes are:
+ * <p>
+ * <table border="1">
+ * <tr>
+ * <th>Name</th>
+ * <th>Symbol</th>
+ * <th>Type</th>
+ * </tr>
+ * <tr>
+ * <td>Subject Attribute</td>
+ * <td>S</td>
+ * <td>String</td>
+ * </tr>
+ * </tr>
+ * <tr>
+ * <td>Predicate Attribute</td>
+ * <td>P</td>
+ * <td>String</td>
+ * </tr>
+ * </tr>
+ * <tr>
+ * <td>Object Attribute</td>
+ * <td>O</td>
+ * <td>String</td>
+ * </tr>
+ * </tr>
+ * <tr>
+ * <td>Context Attribute</td>
+ * <td>C</td>
+ * <td>String</td>
+ * </tr>
+ * </table>
+ */
+public class GeoMesaGeoIndexer extends AbstractAccumuloIndexer implements 
GeoIndexer  {
+
+    private static final Logger logger = 
Logger.getLogger(GeoMesaGeoIndexer.class);
+
+    private static final String FEATURE_NAME = "RDF";
+  
+    private static final String SUBJECT_ATTRIBUTE = "S";
+    private static final String PREDICATE_ATTRIBUTE = "P";
+    private static final String OBJECT_ATTRIBUTE = "O";
+    private static final String CONTEXT_ATTRIBUTE = "C";
+
+    private Set<URI> validPredicates;
+    private Configuration conf;
+    private FeatureStore<SimpleFeatureType, SimpleFeature> featureStore;
+    private FeatureSource<SimpleFeatureType, SimpleFeature> featureSource;
+    private SimpleFeatureType featureType;
+    private boolean isInit = false;
+   
+    //initialization occurs in setConf because index is created using 
reflection
+    @Override
+    public void setConf(Configuration conf) {
+        this.conf = conf;
+        if (!isInit) {
+            try {
+                init();
+                isInit = true;
+            } catch (IOException e) {
+                logger.warn("Unable to initialize index.  Throwing Runtime 
Exception. ", e);
+                throw new RuntimeException(e);
+            }
+        }
+    }
+    
+    @Override
+    public Configuration getConf() {
+        return this.conf;
+    }
+    
+
+    private void init() throws IOException {
+        validPredicates = ConfigUtils.getGeoPredicates(conf);
+
+        DataStore dataStore = createDataStore(conf);
+        
+        try {
+            featureType = getStatementFeatureType(dataStore);
+        } catch (IOException e) {
+            throw new IOException(e);
+        } catch (SchemaException e) {
+            throw new IOException(e);
+        }
+
+        featureSource = dataStore.getFeatureSource(featureType.getName());
+        if (!(featureSource instanceof FeatureStore)) {
+            throw new IllegalStateException("Could not retrieve feature 
store");
+        }
+        featureStore = (FeatureStore<SimpleFeatureType, SimpleFeature>) 
featureSource;
+    }
+
+    private static DataStore createDataStore(Configuration conf) throws 
IOException {
+        // get the configuration parameters
+        Instance instance = ConfigUtils.getInstance(conf);
+        boolean useMock = instance instanceof MockInstance;
+        String instanceId = instance.getInstanceName();
+        String zookeepers = instance.getZooKeepers();
+        String user = ConfigUtils.getUsername(conf);
+        String password = ConfigUtils.getPassword(conf);
+        String auths = ConfigUtils.getAuthorizations(conf).toString();
+        String tableName = ConfigUtils.getGeoTablename(conf);
+        int numParitions = ConfigUtils.getGeoNumPartitions(conf);
+
+        String featureSchemaFormat = "%~#s%" + numParitions + "#r%" + 
FEATURE_NAME
+                + "#cstr%0,3#gh%yyyyMMdd#d::%~#s%3,2#gh::%~#s%#id";
+        // build the map of parameters
+        Map<String, Serializable> params = new HashMap<String, Serializable>();
+        params.put("instanceId", instanceId);
+        params.put("zookeepers", zookeepers);
+        params.put("user", user);
+        params.put("password", password);
+        params.put("auths", auths);
+        params.put("tableName", tableName);
+        params.put("indexSchemaFormat", featureSchemaFormat);
+        params.put("useMock", Boolean.toString(useMock));
+
+        // fetch the data store from the finder
+        return DataStoreFinder.getDataStore(params);
+    }
+
+    private static SimpleFeatureType getStatementFeatureType(DataStore 
dataStore) throws IOException, SchemaException {
+        SimpleFeatureType featureType;
+
+        String[] datastoreFeatures = dataStore.getTypeNames();
+        if (Arrays.asList(datastoreFeatures).contains(FEATURE_NAME)) {
+            featureType = dataStore.getSchema(FEATURE_NAME);
+        } else {
+            String featureSchema = SUBJECT_ATTRIBUTE + ":String," //
+                    + PREDICATE_ATTRIBUTE + ":String," //
+                    + OBJECT_ATTRIBUTE + ":String," //
+                    + CONTEXT_ATTRIBUTE + ":String," //
+                    + Constants.SF_PROPERTY_GEOMETRY + ":Geometry:srid=4326";
+            featureType = SimpleFeatureTypes.createType(FEATURE_NAME, 
featureSchema);
+            dataStore.createSchema(featureType);
+        }
+        return featureType;
+    }
+
+    @Override
+    public void storeStatements(Collection<RyaStatement> ryaStatements) throws 
IOException {
+        // create a feature collection
+        DefaultFeatureCollection featureCollection = new 
DefaultFeatureCollection();
+
+        
+        for (RyaStatement ryaStatement : ryaStatements) {
+
+            Statement statement = 
RyaToRdfConversions.convertStatement(ryaStatement);
+            // if the predicate list is empty, accept all predicates.
+            // Otherwise, make sure the predicate is on the "valid" list
+            boolean isValidPredicate = validPredicates.isEmpty() || 
validPredicates.contains(statement.getPredicate());
+
+            if (isValidPredicate && (statement.getObject() instanceof 
Literal)) {
+                try {
+                    SimpleFeature feature = createFeature(featureType, 
statement);
+                    featureCollection.add(feature);
+                } catch (ParseException e) {
+                    logger.warn("Error getting geo from statement: " + 
statement.toString(), e);
+                }
+            }
+        }
+
+        // write this feature collection to the store
+        if (!featureCollection.isEmpty()) {
+            featureStore.addFeatures(featureCollection);
+        }
+    }
+
+
+    @Override
+    public void storeStatement(RyaStatement statement) throws IOException {
+        storeStatements(Collections.singleton(statement));
+    }
+    
+    private static SimpleFeature createFeature(SimpleFeatureType featureType, 
Statement statement) throws ParseException {
+        String subject = StatementSerializer.writeSubject(statement);
+        String predicate = StatementSerializer.writePredicate(statement);
+        String object = StatementSerializer.writeObject(statement);
+        String context = StatementSerializer.writeContext(statement);
+
+        // create the feature
+        Object[] noValues = {};
+
+        // create the hash
+        String statementId = 
Md5Hash.md5Base64(StatementSerializer.writeStatement(statement));
+        SimpleFeature newFeature = SimpleFeatureBuilder.build(featureType, 
noValues, statementId);
+
+        // write the statement data to the fields
+        Geometry geom = (new 
WKTReader()).read(GeoParseUtils.getWellKnownText(statement));
+        if(geom == null || geom.isEmpty() || !geom.isValid()) {
+            throw new ParseException("Could not create geometry for statement 
" + statement);
+        }
+        newFeature.setDefaultGeometry(geom);
+
+        newFeature.setAttribute(SUBJECT_ATTRIBUTE, subject);
+        newFeature.setAttribute(PREDICATE_ATTRIBUTE, predicate);
+        newFeature.setAttribute(OBJECT_ATTRIBUTE, object);
+        newFeature.setAttribute(CONTEXT_ATTRIBUTE, context);
+
+        // preserve the ID that we created for this feature
+        // (set the hint to FALSE to have GeoTools generate IDs)
+        newFeature.getUserData().put(Hints.USE_PROVIDED_FID, 
java.lang.Boolean.TRUE);
+
+        return newFeature;
+    }
+
+    private CloseableIteration<Statement, QueryEvaluationException> 
performQuery(String type, Geometry geometry,
+            StatementContraints contraints) {
+        List<String> filterParms = new ArrayList<String>();
+
+        filterParms.add(type + "(" + Constants.SF_PROPERTY_GEOMETRY + ", " + 
geometry + " )");
+
+        if (contraints.hasSubject()) {
+            filterParms.add("( " + SUBJECT_ATTRIBUTE + "= '" + 
contraints.getSubject() + "') ");
+        }
+        if (contraints.hasContext()) {
+            filterParms.add("( " + CONTEXT_ATTRIBUTE + "= '" + 
contraints.getContext() + "') ");
+        }
+        if (contraints.hasPredicates()) {
+            List<String> predicates = new ArrayList<String>();
+            for (URI u : contraints.getPredicates()) {
+                predicates.add("( " + PREDICATE_ATTRIBUTE + "= '" + 
u.stringValue() + "') ");
+            }
+            filterParms.add("(" + StringUtils.join(predicates, " OR ") + ")");
+        }
+
+        String filterString = StringUtils.join(filterParms, " AND ");
+        logger.info("Performing geomesa query : " + filterString);
+
+        return getIteratorWrapper(filterString);
+    }
+
+    private CloseableIteration<Statement, QueryEvaluationException> 
getIteratorWrapper(final String filterString) {
+
+        return new CloseableIteration<Statement, QueryEvaluationException>() {
+
+            private FeatureIterator<SimpleFeature> featureIterator = null;
+
+            FeatureIterator<SimpleFeature> getIterator() throws 
QueryEvaluationException {
+                if (featureIterator == null) {
+                    Filter cqlFilter;
+                    try {
+                        cqlFilter = ECQL.toFilter(filterString);
+                    } catch (CQLException e) {
+                        logger.error("Error parsing query: " + filterString, 
e);
+                        throw new QueryEvaluationException(e);
+                    }
+
+                    Query query = new Query(featureType.getTypeName(), 
cqlFilter);
+                    try {
+                        featureIterator = 
featureSource.getFeatures(query).features();
+                    } catch (IOException e) {
+                        logger.error("Error performing query: " + 
filterString, e);
+                        throw new QueryEvaluationException(e);
+                    }
+
+                }
+                return featureIterator;
+            }
+
+            @Override
+            public boolean hasNext() throws QueryEvaluationException {
+                return getIterator().hasNext();
+            }
+
+            @Override
+            public Statement next() throws QueryEvaluationException {
+                SimpleFeature feature = (SimpleFeature) getIterator().next();
+                String subjectString = 
feature.getAttribute(SUBJECT_ATTRIBUTE).toString();
+                String predicateString = 
feature.getAttribute(PREDICATE_ATTRIBUTE).toString();
+                String objectString = 
feature.getAttribute(OBJECT_ATTRIBUTE).toString();
+                String contextString = 
feature.getAttribute(CONTEXT_ATTRIBUTE).toString();
+                Statement statement = 
StatementSerializer.readStatement(subjectString, predicateString, objectString, 
contextString);
+                return statement;
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException("Remove not 
implemented");
+            }
+
+            @Override
+            public void close() throws QueryEvaluationException {
+                getIterator().close();
+            }
+        };
+    }
+
+    @Override
+    public CloseableIteration<Statement, QueryEvaluationException> 
queryEquals(Geometry query, StatementContraints contraints) {
+        return performQuery("EQUALS", query, contraints);
+    }
+
+    @Override
+    public CloseableIteration<Statement, QueryEvaluationException> 
queryDisjoint(Geometry query, StatementContraints contraints) {
+        return performQuery("DISJOINT", query, contraints);
+    }
+
+    @Override
+    public CloseableIteration<Statement, QueryEvaluationException> 
queryIntersects(Geometry query, StatementContraints contraints) {
+        return performQuery("INTERSECTS", query, contraints);
+    }
+
+    @Override
+    public CloseableIteration<Statement, QueryEvaluationException> 
queryTouches(Geometry query, StatementContraints contraints) {
+        return performQuery("TOUCHES", query, contraints);
+    }
+
+    @Override
+    public CloseableIteration<Statement, QueryEvaluationException> 
queryCrosses(Geometry query, StatementContraints contraints) {
+        return performQuery("CROSSES", query, contraints);
+    }
+
+    @Override
+    public CloseableIteration<Statement, QueryEvaluationException> 
queryWithin(Geometry query, StatementContraints contraints) {
+        return performQuery("WITHIN", query, contraints);
+    }
+
+    @Override
+    public CloseableIteration<Statement, QueryEvaluationException> 
queryContains(Geometry query, StatementContraints contraints) {
+        return performQuery("CONTAINS", query, contraints);
+    }
+
+    @Override
+    public CloseableIteration<Statement, QueryEvaluationException> 
queryOverlaps(Geometry query, StatementContraints contraints) {
+        return performQuery("OVERLAPS", query, contraints);
+    }
+
+    @Override
+    public Set<URI> getIndexablePredicates() {
+        return validPredicates;
+    }
+
+    @Override
+    public void flush() throws IOException {
+        // TODO cache and flush features instead of writing them one at a time
+    }
+
+    @Override
+    public void close() throws IOException {
+        flush();
+    }
+
+
+    @Override
+    public String getTableName() {
+       return ConfigUtils.getGeoTablename(conf);
+    }
+
+
+
+  
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/92ddfa59/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoParseUtils.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoParseUtils.java
 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoParseUtils.java
new file mode 100644
index 0000000..5015534
--- /dev/null
+++ 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoParseUtils.java
@@ -0,0 +1,26 @@
+package mvm.rya.indexing.accumulo.geo;
+
+import org.apache.log4j.Logger;
+import org.openrdf.model.Literal;
+import org.openrdf.model.Statement;
+
+import com.vividsolutions.jts.io.ParseException;
+
+public class GeoParseUtils {
+    static final Logger logger = Logger.getLogger(GeoParseUtils.class);
+
+       public static String getWellKnownText(Statement statement) throws 
ParseException {
+           org.openrdf.model.Value v = statement.getObject();
+           if (!(v instanceof Literal)) {
+               throw new ParseException("Statement does not contain Literal: " 
+ statement.toString());
+           }
+       
+           Literal lit = (Literal) v;
+           if (!GeoConstants.XMLSCHEMA_OGC_WKT.equals(lit.getDatatype())) {
+               logger.warn("Literal is not of type " + 
GeoConstants.XMLSCHEMA_OGC_WKT + ": " + statement.toString());
+           }
+       
+           return lit.getLabel().toString();
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/92ddfa59/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoTupleSet.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoTupleSet.java 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoTupleSet.java
new file mode 100644
index 0000000..237b73d
--- /dev/null
+++ 
b/extras/indexing/src/main/java/mvm/rya/indexing/accumulo/geo/GeoTupleSet.java
@@ -0,0 +1,344 @@
+package mvm.rya.indexing.accumulo.geo;
+
+import info.aduna.iteration.CloseableIteration;
+
+import java.util.Map;
+import java.util.Set;
+
+import mvm.rya.indexing.GeoIndexer;
+import mvm.rya.indexing.IndexingExpr;
+import mvm.rya.indexing.IteratorFactory;
+import mvm.rya.indexing.SearchFunction;
+import mvm.rya.indexing.StatementContraints;
+import mvm.rya.indexing.external.tupleSet.ExternalTupleSet;
+import mvm.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
+
+import org.apache.hadoop.conf.Configuration;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.query.algebra.QueryModelVisitor;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Maps;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+
+//Indexing Node for geo expressions to be inserted into execution plan 
+//to delegate geo portion of query to geo index
+public class GeoTupleSet extends ExternalTupleSet {
+
+    private Configuration conf;
+    private GeoIndexer geoIndexer;
+    private IndexingExpr filterInfo;
+   
+
+    public GeoTupleSet(IndexingExpr filterInfo, GeoIndexer geoIndexer) {
+        this.filterInfo = filterInfo;
+        this.geoIndexer = geoIndexer;
+        this.conf = geoIndexer.getConf();
+    }
+
+    @Override
+    public Set<String> getBindingNames() {
+        return filterInfo.getBindingNames();
+    }
+
+    public GeoTupleSet clone() {
+        return new GeoTupleSet(filterInfo, geoIndexer);
+    }
+
+    @Override
+    public double cardinality() {
+        return 0.0; // No idea how the estimate cardinality here.
+    }
+    
+   
+    @Override
+    public String getSignature() {
+        return "(GeoTuple Projection) " + "variables: " + Joiner.on(", 
").join(this.getBindingNames()).replaceAll("\\s+", " ");
+    }
+    
+    
+    
+    @Override
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (!(other instanceof GeoTupleSet)) {
+            return false;
+        }
+        GeoTupleSet arg = (GeoTupleSet) other;
+        return this.filterInfo.equals(arg.filterInfo);
+    }
+    
+    @Override
+    public int hashCode() {
+        int result = 17;
+        result = 31*result + filterInfo.hashCode();
+        
+        return result;
+    }
+    
+    
+
+    /**
+     * Returns an iterator over the result set of the contained IndexingExpr.
+     * <p>
+     * Should be thread-safe (concurrent invocation {@link OfflineIterable} 
this
+     * method can be expected with some query evaluators.
+     */
+    @Override
+    public CloseableIteration<BindingSet, QueryEvaluationException> 
evaluate(BindingSet bindings)
+            throws QueryEvaluationException {
+        
+      
+        URI funcURI = filterInfo.getFunction();
+        SearchFunction searchFunction = (new 
GeoSearchFunctionFactory(conf)).getSearchFunction(funcURI);
+        if(filterInfo.getArguments().length > 1) {
+            throw new IllegalArgumentException("Index functions do not support 
more than two arguments.");
+        }
+        
+        String queryText = filterInfo.getArguments()[0].stringValue();
+        
+        return IteratorFactory.getIterator(filterInfo.getSpConstraint(), 
bindings, queryText, searchFunction);
+    }
+
+
+    
+    //returns appropriate search function for a given URI
+    //search functions used in GeoMesaGeoIndexer to access index
+    public class GeoSearchFunctionFactory {
+        
+        Configuration conf;
+        
+        private final Map<URI, SearchFunction> SEARCH_FUNCTION_MAP = 
Maps.newHashMap();
+
+        public GeoSearchFunctionFactory(Configuration conf) {
+            this.conf = conf;
+        }
+        
+
+        /**
+         * Get a {@link GeoSearchFunction} for a given URI.
+         * 
+         * @param searchFunction
+         * @return
+         */
+        public SearchFunction getSearchFunction(final URI searchFunction) {
+
+            SearchFunction geoFunc = null;
+
+            try {
+                geoFunc = getSearchFunctionInternal(searchFunction);
+            } catch (QueryEvaluationException e) {
+                e.printStackTrace();
+            }
+
+            return geoFunc;
+        }
+
+        private SearchFunction getSearchFunctionInternal(final URI 
searchFunction) throws QueryEvaluationException {
+            SearchFunction sf = SEARCH_FUNCTION_MAP.get(searchFunction);
+
+            if (sf != null) {
+                return sf;
+            } else {
+                throw new QueryEvaluationException("Unknown Search Function: " 
+ searchFunction.stringValue());
+            }
+        }
+
+        private final SearchFunction GEO_EQUALS = new SearchFunction() {
+
+            @Override
+            public CloseableIteration<Statement, QueryEvaluationException> 
performSearch(String queryText,
+                    StatementContraints contraints) throws 
QueryEvaluationException {
+                try {
+                    WKTReader reader = new WKTReader();
+                    Geometry geometry = reader.read(queryText);
+                    CloseableIteration<Statement, QueryEvaluationException> 
statements = geoIndexer.queryWithin(
+                            geometry, contraints);
+                    return statements;
+                } catch (ParseException e) {
+                    throw new QueryEvaluationException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "GEO_EQUALS";
+            };
+        };
+
+        private final SearchFunction GEO_DISJOINT = new SearchFunction() {
+
+            @Override
+            public CloseableIteration<Statement, QueryEvaluationException> 
performSearch(String queryText,
+                    StatementContraints contraints) throws 
QueryEvaluationException {
+                try {
+                    WKTReader reader = new WKTReader();
+                    Geometry geometry = reader.read(queryText);
+                    CloseableIteration<Statement, QueryEvaluationException> 
statements = geoIndexer.queryWithin(
+                            geometry, contraints);
+                    return statements;
+                } catch (ParseException e) {
+                    throw new QueryEvaluationException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "GEO_DISJOINT";
+            };
+        };
+
+        private final SearchFunction GEO_INTERSECTS = new SearchFunction() {
+
+            @Override
+            public CloseableIteration<Statement, QueryEvaluationException> 
performSearch(String queryText,
+                    StatementContraints contraints) throws 
QueryEvaluationException {
+                try {
+                    WKTReader reader = new WKTReader();
+                    Geometry geometry = reader.read(queryText);
+                    CloseableIteration<Statement, QueryEvaluationException> 
statements = geoIndexer.queryWithin(
+                            geometry, contraints);
+                    return statements;
+                } catch (ParseException e) {
+                    throw new QueryEvaluationException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "GEO_INTERSECTS";
+            };
+        };
+
+        private final SearchFunction GEO_TOUCHES = new SearchFunction() {
+
+            @Override
+            public CloseableIteration<Statement, QueryEvaluationException> 
performSearch(String queryText,
+                    StatementContraints contraints) throws 
QueryEvaluationException {
+                try {
+                    WKTReader reader = new WKTReader();
+                    Geometry geometry = reader.read(queryText);
+                    CloseableIteration<Statement, QueryEvaluationException> 
statements = geoIndexer.queryWithin(
+                            geometry, contraints);
+                    return statements;
+                } catch (ParseException e) {
+                    throw new QueryEvaluationException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "GEO_TOUCHES";
+            };
+        };
+
+        private final SearchFunction GEO_CONTAINS = new SearchFunction() {
+
+            @Override
+            public CloseableIteration<Statement, QueryEvaluationException> 
performSearch(String queryText,
+                    StatementContraints contraints) throws 
QueryEvaluationException {
+                try {
+                    WKTReader reader = new WKTReader();
+                    Geometry geometry = reader.read(queryText);
+                    CloseableIteration<Statement, QueryEvaluationException> 
statements = geoIndexer.queryWithin(
+                            geometry, contraints);
+                    return statements;
+                } catch (ParseException e) {
+                    throw new QueryEvaluationException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "GEO_CONTAINS";
+            };
+        };
+
+        private final SearchFunction GEO_OVERLAPS = new SearchFunction() {
+
+            @Override
+            public CloseableIteration<Statement, QueryEvaluationException> 
performSearch(String queryText,
+                    StatementContraints contraints) throws 
QueryEvaluationException {
+                try {
+                    WKTReader reader = new WKTReader();
+                    Geometry geometry = reader.read(queryText);
+                    CloseableIteration<Statement, QueryEvaluationException> 
statements = geoIndexer.queryWithin(
+                            geometry, contraints);
+                    return statements;
+                } catch (ParseException e) {
+                    throw new QueryEvaluationException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "GEO_OVERLAPS";
+            };
+        };
+
+        private final SearchFunction GEO_CROSSES = new SearchFunction() {
+
+            @Override
+            public CloseableIteration<Statement, QueryEvaluationException> 
performSearch(String queryText,
+                    StatementContraints contraints) throws 
QueryEvaluationException {
+                try {
+                    WKTReader reader = new WKTReader();
+                    Geometry geometry = reader.read(queryText);
+                    CloseableIteration<Statement, QueryEvaluationException> 
statements = geoIndexer.queryWithin(
+                            geometry, contraints);
+                    return statements;
+                } catch (ParseException e) {
+                    throw new QueryEvaluationException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "GEO_CROSSES";
+            };
+        };
+
+        private final SearchFunction GEO_WITHIN = new SearchFunction() {
+
+            @Override
+            public CloseableIteration<Statement, QueryEvaluationException> 
performSearch(String queryText,
+                    StatementContraints contraints) throws 
QueryEvaluationException {
+                try {
+                    WKTReader reader = new WKTReader();
+                    Geometry geometry = reader.read(queryText);
+                    CloseableIteration<Statement, QueryEvaluationException> 
statements = geoIndexer.queryWithin(
+                            geometry, contraints);
+                    return statements;
+                } catch (ParseException e) {
+                    throw new QueryEvaluationException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "GEO_WITHIN";
+            };
+        };
+
+        {
+            SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_EQUALS, GEO_EQUALS);
+            SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_DISJOINT, 
GEO_DISJOINT);
+            SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_INTERSECTS, 
GEO_INTERSECTS);
+            SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_TOUCHES, GEO_TOUCHES);
+            SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_CONTAINS, 
GEO_CONTAINS);
+            SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_OVERLAPS, 
GEO_OVERLAPS);
+            SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_CROSSES, GEO_CROSSES);
+            SEARCH_FUNCTION_MAP.put(GeoConstants.GEO_SF_WITHIN, GEO_WITHIN);
+        }
+
+    }
+   
+
+}

Reply via email to