http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/RyaQueryEngineFactory.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/RyaQueryEngineFactory.java
 
b/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/RyaQueryEngineFactory.java
new file mode 100644
index 0000000..91f281c
--- /dev/null
+++ 
b/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/RyaQueryEngineFactory.java
@@ -0,0 +1,75 @@
+package org.apache.rya.indexing.statement.metadata.matching;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.Connector;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.client.ZooKeeperInstance;
+import org.apache.accumulo.core.client.mock.MockInstance;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
+import org.apache.rya.accumulo.AccumuloRdfConfiguration;
+import org.apache.rya.accumulo.query.AccumuloRyaQueryEngine;
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.persist.query.RyaQueryEngine;
+import org.apache.rya.mongodb.MongoConnectorFactory;
+import org.apache.rya.mongodb.MongoDBQueryEngine;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+
+import com.mongodb.MongoClient;
+
+/**
+ * THis class creates the appropriate {@link RyaQueryEngine} based on the type 
of
+ * {@link RdfCloudTripleStoreConfiguration} object that is passed in and 
whether or not
+ * Rya is configured to use Mongo.
+ *
+ */
+public class RyaQueryEngineFactory {
+
+    
+    @SuppressWarnings("unchecked")
+    public static <C extends RdfCloudTripleStoreConfiguration> 
RyaQueryEngine<C> getQueryEngine(RdfCloudTripleStoreConfiguration conf) { 
+        if(conf instanceof AccumuloRdfConfiguration) {
+            AccumuloRdfConfiguration aConf = (AccumuloRdfConfiguration) conf;
+            Instance instance;
+            String instanceName = aConf.get("sc.cloudbase.instancename");
+            String user = aConf.get("sc.cloudbase.username");
+            String password = aConf.get("sc.cloudbase.password");
+            if(aConf.getBoolean(".useMockInstance", false)) {
+                instance = new MockInstance(instanceName);
+            } else {
+                String zookeepers = aConf.get("sc.cloudbase.zookeepers");
+                instance = new ZooKeeperInstance(instanceName, zookeepers);
+            }
+            Connector conn;
+            try {
+                conn = instance.getConnector(user, new 
PasswordToken(password));
+            } catch (AccumuloException | AccumuloSecurityException e) {
+                throw new RuntimeException(e);
+            }
+            return (RyaQueryEngine<C>) new AccumuloRyaQueryEngine(conn, aConf);
+        } else if(conf instanceof MongoDBRdfConfiguration && 
conf.getBoolean("sc.useMongo", false)) {
+            MongoClient client = MongoConnectorFactory.getMongoClient(conf);
+            return (RyaQueryEngine<C>) new 
MongoDBQueryEngine((MongoDBRdfConfiguration) conf, client);
+        } else {
+            throw new IllegalArgumentException("Invalid configuration type.");
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataExternalSetMatcherFactory.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataExternalSetMatcherFactory.java
 
b/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataExternalSetMatcherFactory.java
new file mode 100644
index 0000000..5020a0e
--- /dev/null
+++ 
b/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataExternalSetMatcherFactory.java
@@ -0,0 +1,50 @@
+package org.apache.rya.indexing.statement.metadata.matching;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import 
org.apache.rya.indexing.external.matching.AbstractExternalSetMatcherFactory;
+import org.apache.rya.indexing.external.matching.ExternalSetMatcher;
+import org.apache.rya.indexing.external.matching.JoinSegment;
+import org.apache.rya.indexing.external.matching.JoinSegmentMatcher;
+import org.apache.rya.indexing.external.matching.OptionalJoinSegment;
+import org.apache.rya.indexing.external.matching.OptionalJoinSegmentMatcher;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+
+/**
+ * This class builds the appropriate {@link ExternalSetMatcher}s based on the
+ * type of {@link QuerySegment} that is passed in.  
+ *
+ */
+public class StatementMetadataExternalSetMatcherFactory
+        extends AbstractExternalSetMatcherFactory<StatementMetadataNode<?>> {
+
+    @Override
+    protected ExternalSetMatcher<StatementMetadataNode<?>> 
getJoinSegmentMatcher(
+            JoinSegment<StatementMetadataNode<?>> segment) {
+        return new JoinSegmentMatcher<StatementMetadataNode<?>>(segment,
+                new MetadataNodeToSegmentConverter());
+    }
+
+    @Override
+    protected ExternalSetMatcher<StatementMetadataNode<?>> 
getOptionalJoinSegmentMatcher(
+            OptionalJoinSegment<StatementMetadataNode<?>> segment) {
+        return new 
OptionalJoinSegmentMatcher<StatementMetadataNode<?>>(segment,
+                new MetadataNodeToSegmentConverter());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataExternalSetProvider.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataExternalSetProvider.java
 
b/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataExternalSetProvider.java
new file mode 100644
index 0000000..f430b1b
--- /dev/null
+++ 
b/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataExternalSetProvider.java
@@ -0,0 +1,113 @@
+package org.apache.rya.indexing.statement.metadata.matching;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.api.resolver.RdfToRyaConversions;
+import org.apache.rya.indexing.external.matching.ExternalSetProvider;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.openrdf.model.URI;
+import org.openrdf.model.vocabulary.RDF;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.Var;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * This class extracts all valid {@Link StatementMetadataNode}s from the 
provided {@link QuerySegment}s.
+ *
+ */
+public class StatementMetadataExternalSetProvider implements 
ExternalSetProvider<StatementMetadataNode<?>> {
+
+    private List<RyaURI> expectedURI = 
Arrays.asList(RdfToRyaConversions.convertURI(RDF.SUBJECT),
+            RdfToRyaConversions.convertURI(RDF.PREDICATE), 
RdfToRyaConversions.convertURI(RDF.OBJECT),
+            RdfToRyaConversions.convertURI(RDF.TYPE));
+    private Multimap<Var, StatementPattern> reifiedQueries;
+    private Set<RyaURI> metadataProperties;
+    private RdfCloudTripleStoreConfiguration conf;
+
+    public 
StatementMetadataExternalSetProvider(RdfCloudTripleStoreConfiguration conf) {
+        this.metadataProperties = conf.getStatementMetadataProperties();
+        this.conf = conf;
+    }
+
+    /**
+     * This method extracts all {@link StatementMetadataNode}s from the 
provided {@link QuerySegment}.
+     * It looks through the provided QuerySegment for all combinations of 
{@link StatementPattern}s that 
+     * represent a reified query and combines those into a 
StatementPatternNode.  A StatementPattern cannot
+     * be used in more than one reified query and StatementPatternNode.
+     */
+    @Override
+    public List<StatementMetadataNode<?>> 
getExternalSets(QuerySegment<StatementMetadataNode<?>> segment) {
+
+        reifiedQueries = HashMultimap.create();
+
+        List<StatementMetadataNode<?>> metadataList = new ArrayList<>();
+        for (QueryModelNode node : segment.getUnOrderedNodes()) {
+            if (node instanceof StatementPattern) {
+                StatementPattern sp = (StatementPattern) node;
+                reifiedQueries.put(sp.getSubjectVar(), sp);
+            }
+        }
+
+        for (Var var : reifiedQueries.keySet()) {
+            Collection<StatementPattern> patterns = 
removeInvalidProperties(reifiedQueries.get(var));
+            if (StatementMetadataNode.verifyHasCorrectTypePattern(patterns)) {
+                metadataList.add(new StatementMetadataNode<>(patterns, conf));
+            }
+        }
+
+        return metadataList;
+    }
+
+    @Override
+    public Iterator<List<StatementMetadataNode<?>>> getExternalSetCombos(
+            QuerySegment<StatementMetadataNode<?>> segment) {
+        Set<List<StatementMetadataNode<?>>> combos = new HashSet<>();
+        combos.add(getExternalSets(segment));
+        return combos.iterator();
+    }
+
+    private Set<StatementPattern> 
removeInvalidProperties(Collection<StatementPattern> patterns) {
+
+        Set<StatementPattern> finalPatterns = new HashSet<>();
+        
+        for (StatementPattern pattern : patterns) {
+            Var var = pattern.getPredicateVar();
+            if (var.getValue() != null && var.getValue() instanceof URI) {
+                RyaURI uri = RdfToRyaConversions.convertURI((URI) 
var.getValue());
+                if(expectedURI.contains(uri) || 
metadataProperties.contains(uri)) {
+                    finalPatterns.add(pattern);
+                }
+            }
+        }
+        return finalPatterns;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataNode.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataNode.java
 
b/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataNode.java
new file mode 100644
index 0000000..85b048e
--- /dev/null
+++ 
b/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataNode.java
@@ -0,0 +1,638 @@
+package org.apache.rya.indexing.statement.metadata.matching;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import static java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+import java.util.Set;
+
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.RdfCloudTripleStoreUtils;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.api.domain.StatementMetadata;
+import org.apache.rya.api.persist.RyaDAOException;
+import org.apache.rya.api.persist.query.RyaQueryEngine;
+import org.apache.rya.api.resolver.RdfToRyaConversions;
+import org.apache.rya.api.resolver.RyaToRdfConversions;
+import org.apache.rya.rdftriplestore.evaluation.ExternalBatchingIterator;
+import org.openrdf.model.BNode;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.vocabulary.RDF;
+import org.openrdf.query.Binding;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.Var;
+import org.openrdf.query.algebra.evaluation.QueryBindingSet;
+import org.openrdf.query.algebra.evaluation.impl.ExternalSet;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+
+import info.aduna.iteration.CloseableIteration;
+
+/**
+ * This class provides users with the ability to issue reified queries to Rya. 
 As opposed to a single triple
+ * representing a statement, a reified query consists of a number of triples 
that all describe the same
+ * statement.  For example, instead of having the single statement 
(http://Bob, http://worksAt,http://CoffeeShop),
+ * the reified statement representing this triple would be the collection of 
triples: {(_blankNode, RDF.TYPE, RDF.STATEMENT),
+ * (_blankNode, RDF.SUBJECT, http://Bob), (_blankNode, RDF.PREDICATE, 
http://worksAt), (_blankNode, RDF.OBJECT, http://CoffeeShop)}.
+ * The advantage of expanding the statement into a collection of triples in 
this way is that additional assertions can be made about the
+ * statement.  For example, we could use the triple (_blankNode, 
<http://createdOn>, <http://date#1/2/17>) to indicate that the statement
+ * was created on 1/2/17.  The drawback of reification is that is it 
inefficient.  It takes four triples to specify what was originally
+ * specified with one triple.  So reificiation is expensive from a storage 
perspective.  It is also expensive from a query perspective in
+ * that three joins are required to evaluate a query that is reduced to a 
single scan in non-reified form.
+ * 
+ * This class provides Rya with the ability to issue reified queries even 
though statements are not reified.  Each {@link RyaStatement}
+ * contains a {@link StatementMetadata} field that allows users to store 
additional metadata about a given statement.  When a user
+ * issues a reified query (possibly containing StatementPatterns about 
metadata for that statement), the {@link StatementPattern}s for
+ * that parsed query are used to create this class.  Upon construction, the 
StatementMetadataNode validates that the
+ * collection of StatementPatterns represents a reified query, and then 
evaluates the reified query using a single scan over a range
+ * determined by the subject, predicate, and object portions of the reified 
query.  If additional metadata properties are specified in
+ * the reified query, the results of the initial scan are filtered client side 
by comparing the user specified properties with the
+ * StatementMetadata extracted from each of the results.  This class allows 
users to issue queries about RyaStatements and any contextual
+ * properties without the inefficiencies associated with reification.
+ *
+ * @param <C> - Configuration object 
+ */
+public class StatementMetadataNode<C extends RdfCloudTripleStoreConfiguration> 
extends ExternalSet implements ExternalBatchingIterator {
+
+    private static final RyaURI TYPE_ID_URI = new RyaURI(RDF.TYPE.toString());
+    private static final RyaURI SUBJ_ID_URI = new 
RyaURI(RDF.SUBJECT.toString());
+    private static final RyaURI PRED_ID_URI = new 
RyaURI(RDF.PREDICATE.toString());
+    private static final RyaURI OBJ_ID_URI = new RyaURI(RDF.OBJECT.toString());
+    private static final RyaURI STATEMENT_ID_URI = new 
RyaURI(RDF.STATEMENT.toString());
+
+    private StatementPattern statement;
+    private Map<RyaURI, Var> properties;
+    private Collection<StatementPattern> patterns;
+    private List<RyaURI> uriList = Arrays.asList(TYPE_ID_URI, SUBJ_ID_URI, 
PRED_ID_URI, OBJ_ID_URI);
+    private C conf;
+    private Set<String> bindingNames;
+    private RyaQueryEngine<C> queryEngine;
+
+    public StatementMetadataNode(final Collection<StatementPattern> patterns, 
C conf) {
+        this.conf = conf;
+        this.patterns = patterns;
+        verifySameSubjects(patterns);
+        verifyAllPredicatesAreConstants(patterns);
+        boolean correctForm = verifyHasCorrectTypePattern(patterns);
+        if(!correctForm) {
+            throw new IllegalArgumentException("Invalid reified 
StatementPatterns.");
+        }
+        setStatementPatternAndProperties(patterns);
+    }
+    
+    /**
+     * Get {@link StatementPattern}s representing the underlying reified query.
+     * 
+     * @return Collection of StatementPatterns
+     */
+    public Collection<StatementPattern> getReifiedStatementPatterns() {
+        return patterns;
+    }
+
+    /**
+     * Verify the Subject for all of the patterns is the same and that all
+     * Subjects are {@link BNode}s.
+     *
+     * @param patterns
+     *            - The patterns to check.
+     * @throws IllegalStateException
+     *             If all of the Subjects are not the same.
+     */
+    private static void verifySameSubjects(Collection<StatementPattern> 
patterns) throws IllegalStateException {
+        requireNonNull(patterns);
+
+        final Iterator<StatementPattern> it = patterns.iterator();
+        final Var subject = it.next().getSubjectVar();
+
+        while (it.hasNext()) {
+            final StatementPattern pattern = it.next();
+            if (!pattern.getSubjectVar().equals(subject)) {
+                throw new IllegalStateException("At least one of the patterns 
has a different subject from the others. "
+                        + "All subjects must be the same.");
+            }
+        }
+    }
+
+    /**
+     * Verifies all of the Statement Patterns have Constants for their
+     * predicates.
+     *
+     * @param patterns
+     *            - The patterns to check. (not null)
+     * @throws IllegalStateException
+     *             A pattern has a variable predicate.
+     */
+    private static void verifyAllPredicatesAreConstants(final 
Collection<StatementPattern> patterns)
+            throws IllegalStateException {
+        requireNonNull(patterns);
+
+        for (final StatementPattern pattern : patterns) {
+            if (!pattern.getPredicateVar().isConstant()) {
+                throw new IllegalStateException(
+                        "The Predicate of a Statement Pattern must be 
constant. Pattern: " + pattern);
+            }
+        }
+    }
+
+    /**
+     * Verifies StatementPatterns define a reified pattern with associated
+     * metadata properties.
+     *
+     * @param patterns
+     *            - The patterns to check. (not null)
+     * @throws IllegalStateException
+     *             No Type or the wrong Type is specified by the patterns.
+     */
+    public static boolean verifyHasCorrectTypePattern(final 
Collection<StatementPattern> patterns)
+            throws IllegalStateException {
+        requireNonNull(patterns);
+
+        boolean subjFound = false;
+        boolean objFound = false;
+        boolean predFound = false;
+        boolean statementFound = false;
+        boolean valid = true;
+
+        for (final StatementPattern pattern : patterns) {
+            final RyaURI predicate = new 
RyaURI(pattern.getPredicateVar().getValue().toString());
+
+            if (predicate.equals(TYPE_ID_URI)) {
+                final RyaURI statementID = new 
RyaURI(pattern.getObjectVar().getValue().stringValue());
+                if (statementID.equals(STATEMENT_ID_URI)) {
+                    statementFound = true;
+                } else {
+                   //contains more than one Statement containing TYPE_ID_URI 
as Predicate
+                   //and STATEMENT_ID_URI as Object
+                   valid = false;
+                }
+            }
+
+            if (predicate.equals(SUBJ_ID_URI)) {
+                if(!subjFound) {
+                    subjFound = true;
+                } else {
+                  //contains more than Subject SP
+                    valid = false;
+                }
+                
+                
+            }
+
+            if (predicate.equals(PRED_ID_URI)) {
+                if(!predFound) {
+                    predFound = true;
+                } else {
+                  //contains more than one Predicate SP
+                    valid = false;
+                }
+            }
+
+            if (predicate.equals(OBJ_ID_URI)) {
+                if(!objFound) {
+                    objFound = true;
+                } else {
+                  //contains more than one Object SP
+                    valid = false;
+                }
+            }
+        }
+
+        return valid && statementFound && subjFound && predFound && objFound;
+    }
+    
+    /**
+     * Constructs a {@link StatementPattern} from the StatementPatterns 
representing a reified query.
+     * This StatementPattern has as a subject, the object of the 
StatementPattern containing the predicate
+     * {@link RDF#SUBJECT}. This StatementPattern has as predicate, the object 
of the StatementPattern containing the predicate
+     * {@link RDF#PREDICATE}. This StatementPattern has as an object, the 
object of the StatementPattern containing the predicate
+     * {@link RDF#OBJECT}.  This method also builds a map between all 
predicates that are not of the above type and the object {@link Var}s
+     * they are associated with.  This map contains the user specified 
metadata properties and is used for comparison with the
+     * metadata properties extracted from RyaStatements passed back by the 
{@link RyaQueryEngine}.
+     * 
+     * @param patterns - collection of patterns representing a reified query
+     */
+    private void setStatementPatternAndProperties(Collection<StatementPattern> 
patterns){ 
+        
+        StatementPattern sp = new StatementPattern();
+        Map<RyaURI, Var> properties = new HashMap<>();
+        
+        for (final StatementPattern pattern : patterns) {
+            final RyaURI predicate = new 
RyaURI(pattern.getPredicateVar().getValue().toString());
+
+            if(!uriList.contains(predicate)) {
+                Var objVar = pattern.getObjectVar();
+                properties.put(predicate, objVar);
+                continue;
+            } 
+            
+            if (predicate.equals(SUBJ_ID_URI)) {
+                sp.setSubjectVar(pattern.getObjectVar());
+            }
+
+            if (predicate.equals(PRED_ID_URI)) {
+                sp.setPredicateVar(pattern.getObjectVar());
+            }
+
+            if (predicate.equals(OBJ_ID_URI)) {
+               sp.setObjectVar(pattern.getObjectVar());
+            }
+        }
+        this.statement = sp;
+        this.properties = properties;
+    }
+
+    /**
+     * This method pairs each {@link BindingSet} in the specified collection 
with the StatementPattern constraints
+     * and issues a query to Rya using the {@link RyaQueryEngine}.  
+     */
+    @Override
+    public CloseableIteration<BindingSet, QueryEvaluationException> 
evaluate(Collection<BindingSet> bindingset)
+            throws QueryEvaluationException {
+        queryEngine = RyaQueryEngineFactory.getQueryEngine(conf);
+        Set<Map.Entry<RyaStatement, BindingSet>> statements = new HashSet<>();
+        Iterator<BindingSet> iter = bindingset.iterator();
+        while(iter.hasNext()) {
+            BindingSet bs = iter.next();
+            statements.add(new 
RdfCloudTripleStoreUtils.CustomEntry<RyaStatement, 
BindingSet>(getRyaStatementFromBindings(bs), bs));
+        }
+        
+        final CloseableIteration<? extends Entry<RyaStatement, BindingSet>, 
RyaDAOException> iteration;
+        try {
+            iteration = queryEngine.queryWithBindingSet(statements, conf);
+        } catch (RyaDAOException e) {
+            throw new RuntimeException(e);
+        }
+        
+       return new PropertyFilterAndBindingSetJoinIteration(iteration, 
properties, statement);
+    }
+    
+    /**
+     * Uses StatementPattern constraints to form a RyaStatement, and fills in 
any null values with
+     * {@link BindingSet} values corresponding to the variable for that 
position.  
+     * 
+     * @param bs
+     * @return RyaStatement whose values are determined by StatementPattern 
and BindingSet constraints
+     */
+    private RyaStatement getRyaStatementFromBindings(BindingSet bs) {
+        
+        Value subjValue = getVarValue(statement.getSubjectVar(),bs);
+        Value predValue = getVarValue(statement.getPredicateVar(),bs);
+        Value objValue = getVarValue(statement.getObjectVar(),bs);
+        RyaURI subj = null;
+        RyaURI pred = null;
+        RyaType obj = null;
+               
+        
+        if(subjValue != null) {
+            Preconditions.checkArgument(subjValue instanceof URI);
+            subj = RdfToRyaConversions.convertURI((URI) subjValue);
+        }
+        
+        if(predValue != null) {
+            Preconditions.checkArgument(predValue instanceof URI);
+            pred = RdfToRyaConversions.convertURI((URI) predValue);
+        }
+        
+        if(objValue != null) {
+            obj = RdfToRyaConversions.convertValue(objValue);
+        }
+        return new RyaStatement(subj, pred, obj);
+    }
+    
+    /**
+     * Assigns BindingSet values for any {@link Var} whose {@link Value} is 
null.
+     * Returns the {@link Value} associated with Var (if it has one), 
otherwise returns the BindingSet Value
+     * corresponding to {@link Var#getName()}.  If no such Binding exits, this 
method returns null.
+     * 
+     * @param var
+     * @param bindings
+     * @return Value 
+     */
+    private Value getVarValue(Var var, BindingSet bindings) {
+        if (var == null) {
+            return null;
+        }
+        else if (var.hasValue()) {
+            return var.getValue();
+        }
+        else {
+            return bindings.getValue(var.getName());
+        }
+    }
+
+    @Override
+    public CloseableIteration<BindingSet, QueryEvaluationException> 
evaluate(BindingSet bindings)
+            throws QueryEvaluationException {
+        return evaluate(Collections.singleton(bindings));
+    }
+    
+    
+    @Override
+    public boolean equals(Object other) {
+        
+        if(this == other ) {
+            return true;
+        }
+        
+        if(other instanceof StatementMetadataNode) {
+            StatementMetadataNode<?> meta = (StatementMetadataNode<?>) other;
+            if(meta.patterns.size() != this.patterns.size()) {
+                return false;
+            }
+            
+            if(this.patterns.size() != meta.patterns.size()) {
+                return false;
+            }
+            
+            Set<StatementPattern> thisSet = new HashSet<>(patterns);
+            Set<StatementPattern> thatSet = new HashSet<>(meta.patterns);
+            return thisSet.equals(thatSet);
+        } else {
+            return false;
+        }
+    }
+    
+    @Override
+    public int hashCode() {
+        int hashcode = 0;
+        for(StatementPattern sp: patterns) {
+            hashcode += sp.hashCode();
+        }
+        return hashcode;
+    }
+    
+    @Override
+    public Set<String> getBindingNames() {
+        if(bindingNames == null) {
+            bindingNames = getVariableNames();
+        } 
+        return bindingNames;
+    }
+    
+    @Override
+    public Set<String> getAssuredBindingNames() {
+        return getBindingNames();
+    }
+    
+    @Override
+    public String getSignature() {
+        return "StatementMetadataNode(" + 
Joiner.on(",").join(getBindingNames()) + ")";
+    }
+    
+    @Override
+    public String toString() {
+        return getSignature();
+    }
+    
+    private Set<String> getVariableNames() {
+        Set<String> vars = new HashSet<>();
+        for(StatementPattern pattern : patterns) {
+            for(Var var: pattern.getVarList()) {
+                if(var.getValue() == null) {
+                    vars.add(var.getName());
+                }
+            }
+        }
+        return vars;
+    }
+    
+    
+    /**
+     * This is an {@link CloseableIteration} class that serves a number of 
purposes.  It's primary purpose is to
+     * filter a CloseableIteration over {@link 
Map.Entry<RyaStatement,BindingSet>} using a specified property Map
+     * from {@link RyaURI} to {@link org.openrdf.query.algebra.Var}.  This 
Iteration iterates over the Entries in the user specified Iteration,
+     * comparing properties in the {@link StatementMetadata} Map contained in 
the RyaStatements with the property Map for this class.
+     * If the properties match, a {@BindingSet} is formed from the 
RyaStatement/Properties and joined (if possible) with the
+     * BindingSet taken from the Map.Entry.  If the RyaStatement/Property 
BindingSet cannot be formed or joined the the Entry BindingSet,
+     * the Entry in the user specified Iteration is filtered out.  So this 
class converts Iterations, filters according to the
+     * specified property Map, and joins the BindingSet formed from the 
RyaStatements/Properties with the Entry BindingSet. 
+}.   
+     *
+     */
+    class PropertyFilterAndBindingSetJoinIteration implements 
CloseableIteration<BindingSet, QueryEvaluationException> {
+
+        private CloseableIteration<? extends Entry<RyaStatement, BindingSet>, 
RyaDAOException> statements;
+        private Map<RyaURI, Var> properties;
+        private StatementPattern sp;
+        private BindingSet next;
+        private boolean hasNextCalled = false;
+        private boolean hasNext = false;
+        
+        public PropertyFilterAndBindingSetJoinIteration(CloseableIteration<? 
extends Entry<RyaStatement, BindingSet>, 
+                RyaDAOException> statements, Map<RyaURI, Var> properties, 
StatementPattern sp) {
+            this.statements = statements;
+            this.properties = properties;
+            this.sp = sp;
+        }
+        
+        @Override
+        public boolean hasNext() throws QueryEvaluationException {
+            if (!hasNextCalled) {
+                hasNextCalled = true;
+                hasNext = false;
+                Optional<BindingSet> bs;
+                try {
+                    bs = getNext();
+                    if (bs.isPresent()) {
+                        next = bs.get();
+                        hasNext = true;
+                    }
+                    if(!hasNext) {
+                        queryEngine.close();
+                    }
+                    return hasNext;
+                } catch (RyaDAOException | IOException e) {
+                    throw new QueryEvaluationException(e);
+                }
+            } else {
+                return hasNext;
+            }
+        }
+
+        @Override
+        public BindingSet next() throws QueryEvaluationException {
+            
+            if(hasNextCalled) {
+                if(!hasNext) {
+                    throw new NoSuchElementException();
+                }
+                hasNextCalled = false;
+                return next;
+            } else {
+                hasNext();
+                if(!hasNext) {
+                    throw new NoSuchElementException();
+                }
+                hasNextCalled = false;
+                return next;
+            }
+        }
+
+        @Override
+        public void remove() throws QueryEvaluationException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void close() throws QueryEvaluationException {
+            try {
+                statements.close();
+            } catch ( RyaDAOException e) {
+                throw new QueryEvaluationException(e);
+            }
+        }
+        
+        /**
+         * Fast-forwards Iteration to next valid Entry and builds the 
BindingSet.
+         * 
+         * @return BindingSet 
+         * @throws RyaDAOException
+         */
+        private Optional<BindingSet> getNext() throws RyaDAOException {
+            Optional<BindingSet> optionalBs = Optional.empty();
+            while(statements.hasNext() && !optionalBs.isPresent()) {
+                Map.Entry<RyaStatement, BindingSet> next = statements.next();
+                optionalBs = buildBindingSet(next.getKey(), next.getValue());
+            }
+            return optionalBs;
+        }
+        
+        /**
+         * Builds BindingSet from Entry if possible. Otherwise returns an 
empty Optional if no
+         * valid BindingSet can be built.  Valid BindingSet can be built if 
this class's
+         * property Map is consistent with {@link StatementMetadata} 
properties for the specified
+         * RyaStatement and if the BindingSet built form the StatementMetadata 
properties can be
+         * joined with specified BindingSet. 
+         * 
+         * @param statement - RyaStatement
+         * @param bindingSet - BindingSet
+         * @return - Optional containing BindingSet is a valid BindingSet 
could be built
+         */
+        private Optional<BindingSet> buildBindingSet(RyaStatement statement, 
BindingSet bindingSet) {
+            
+            QueryBindingSet bs = new QueryBindingSet();
+            Optional<BindingSet> optPropBs = 
buildPropertyBindingSet(statement);
+            if(!optPropBs.isPresent()) {
+                return Optional.empty();
+            }
+            BindingSet propBs = optPropBs.get();
+            BindingSet spBs = buildBindingSetFromStatementPattern(statement);
+            if(!canJoinBindingSets(spBs, propBs)) {
+                return Optional.empty();
+            }
+            bs.addAll(spBs);
+            bs.addAll(propBs);
+            if(!canJoinBindingSets(bs, bindingSet)) {
+                return Optional.empty();
+            }
+            bs.addAll(bindingSet);
+            return Optional.of(bs);
+          
+        }
+        
+        /**
+         * Verifies whether this class's property Map is consistent with 
StatementMetadata properties
+         * for specified RyaStatement.  If consistent, this method builds the 
associated BindingSet otherwise
+         * an empty Optional is returned.
+         * 
+         * @param statement
+         * @return
+         */
+        private Optional<BindingSet> buildPropertyBindingSet(RyaStatement 
statement) {
+            StatementMetadata metadata = statement.getMetadata();
+            Map<RyaURI, RyaType> statementProps = metadata.getMetadata();
+            QueryBindingSet bs = new QueryBindingSet();
+            for(Map.Entry<RyaURI, Var> entry : properties.entrySet()) {
+                RyaURI key = entry.getKey();
+                Var var = entry.getValue();
+                if(!statementProps.containsKey(key)) {
+                    return Optional.empty();
+                } else {
+                    Value val = 
RyaToRdfConversions.convertValue(statementProps.get(key));
+                    if(var.getValue() == null) {
+                        bs.addBinding(var.getName(), val);
+                    } else if (!var.getValue().equals(val)){
+                        return Optional.empty();
+                    }
+                }
+            }
+            return Optional.of(bs);
+        }
+        
+        /**
+         * Builds the BindingSet from the specified RyaStatement by using the 
StatementPattern
+         * for this class.  This method checks whether StatementPattern has a 
{@link Value} for each
+         * position {@link org.openrdf.query.algebra.Var} (Subject, Predicate, 
Object).  If it doesn't have a Value, a Binding is created
+         * from the RyaStatement using the {@link RyaType} for the 
corresponding position (Subject, Predicate, Object).
+         * 
+         * @param statement
+         * @return BindingSet
+         */
+        private BindingSet buildBindingSetFromStatementPattern(RyaStatement 
statement) {
+            Var subjVar = sp.getSubjectVar();
+            Var predVar = sp.getPredicateVar();
+            Var objVar = sp.getObjectVar();
+            QueryBindingSet bs = new QueryBindingSet();
+            
+            if(subjVar.getValue() == null) {
+                bs.addBinding(subjVar.getName(), 
RyaToRdfConversions.convertValue(statement.getSubject()));
+            }
+            
+            if(predVar.getValue() == null ) {
+                bs.addBinding(predVar.getName(), 
RyaToRdfConversions.convertValue(statement.getPredicate()));
+            }
+            
+            if(objVar.getValue() == null) {
+                bs.addBinding(objVar.getName(), 
RyaToRdfConversions.convertValue(statement.getObject()));
+            }
+            
+            return bs;
+        }
+        
+        private boolean canJoinBindingSets(BindingSet bs1, BindingSet bs2) {
+            for(Binding b: bs1) {
+                String name = b.getName();
+                Value val = b.getValue();
+                if(bs2.hasBinding(name) && (!bs2.getValue(name).equals(val))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+    
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataOptimizer.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataOptimizer.java
 
b/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataOptimizer.java
new file mode 100644
index 0000000..02c174e
--- /dev/null
+++ 
b/extras/indexing/src/main/java/org/apache/rya/indexing/statement/metadata/matching/StatementMetadataOptimizer.java
@@ -0,0 +1,92 @@
+package org.apache.rya.indexing.statement.metadata.matching;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.indexing.external.matching.AbstractExternalSetOptimizer;
+import org.apache.rya.indexing.external.matching.BasicRater;
+import org.apache.rya.indexing.external.matching.ExternalSetMatcher;
+import org.apache.rya.indexing.external.matching.ExternalSetProvider;
+import org.apache.rya.indexing.external.matching.QueryNodeListRater;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.Dataset;
+import org.openrdf.query.algebra.TupleExpr;
+
+import com.google.common.base.Optional;
+
+public class StatementMetadataOptimizer extends 
AbstractExternalSetOptimizer<StatementMetadataNode<?>>implements Configurable {
+
+    private StatementMetadataExternalSetMatcherFactory factory = new 
StatementMetadataExternalSetMatcherFactory();
+    private RdfCloudTripleStoreConfiguration conf;
+    public boolean init = false;
+    public StatementMetadataExternalSetProvider provider;
+
+    public StatementMetadataOptimizer() {}
+    
+    public StatementMetadataOptimizer(RdfCloudTripleStoreConfiguration conf) {
+        setConf(conf);
+    }
+
+    @Override
+    public final void setConf(Configuration conf) {
+        checkNotNull(conf);
+        if (!init) {
+            try {
+                this.conf = (RdfCloudTripleStoreConfiguration) conf;
+                provider = new StatementMetadataExternalSetProvider(this.conf);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+            init = true;
+        }
+    }
+    
+    @Override
+    public Configuration getConf() {
+        return conf;
+    }
+    
+    @Override
+    public void optimize(TupleExpr tupleExpr, Dataset dataset, BindingSet 
bindings) {
+        if(!init) {
+            throw new IllegalStateException("Optimizer has not been properly 
initialized.  Configuration must be set to initialize this class.");
+        }
+        super.optimize(tupleExpr, dataset, bindings);
+    }
+
+    @Override
+    protected ExternalSetMatcher<StatementMetadataNode<?>> 
getMatcher(QuerySegment<StatementMetadataNode<?>> segment) {
+        return factory.getMatcher(segment);
+    }
+
+    @Override
+    protected ExternalSetProvider<StatementMetadataNode<?>> getProvider() {
+        return provider;
+    }
+
+    @Override
+    protected Optional<QueryNodeListRater> 
getNodeListRater(QuerySegment<StatementMetadataNode<?>> segment) {
+        return Optional.of(new BasicRater(segment.getOrderedNodes()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/ValidIndexCombinationGeneratorTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/ValidIndexCombinationGeneratorTest.java 
b/extras/indexing/src/test/java/ValidIndexCombinationGeneratorTest.java
deleted file mode 100644
index 08782e7..0000000
--- a/extras/indexing/src/test/java/ValidIndexCombinationGeneratorTest.java
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import static org.junit.Assert.*;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import junit.framework.Assert;
-import 
org.apache.rya.indexing.IndexPlanValidator.IndexedExecutionPlanGenerator;
-import 
org.apache.rya.indexing.IndexPlanValidator.ValidIndexCombinationGenerator;
-import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
-import org.apache.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
-
-import org.junit.Test;
-import org.openrdf.query.MalformedQueryException;
-import org.openrdf.query.algebra.Projection;
-import org.openrdf.query.algebra.TupleExpr;
-import org.openrdf.query.parser.ParsedQuery;
-import org.openrdf.query.parser.sparql.SPARQLParser;
-
-import com.google.common.collect.Lists;
-
-
-public class ValidIndexCombinationGeneratorTest {
-
-    
-    
-    
-    
-
-    @Test
-    public void singleIndex() {
-        String q1 = ""//
-                + "SELECT ?f ?m ?d " //
-                + "{" //
-                + "  ?f a ?m ."//
-                + "  ?m <http://www.w3.org/2000/01/rdf-schema#label> ?d ."//
-                + "  ?d <uri:talksTo> ?f . "//
-                + "  ?f <uri:hangOutWith> ?m ." //
-                + "  ?m <uri:hangOutWith> ?d ." //
-                + "  ?f <uri:associatesWith> ?m ." //
-                + "  ?m <uri:associatesWith> ?d ." //
-                + "}";//
-        
-        
-       
-        
-        
-
-        SPARQLParser parser = new SPARQLParser();
-        ParsedQuery pq1 = null;
-       
-        
-        SimpleExternalTupleSet extTup1 = null;
-        
-        
-        
-        
-        
-        
-        try {
-            pq1 = parser.parseQuery(q1, null);
-            
-           
-
-            extTup1 = new SimpleExternalTupleSet((Projection) 
pq1.getTupleExpr());
-            
-          
-        } catch (MalformedQueryException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        
-        List<ExternalTupleSet> indexList = Lists.newArrayList();
-        indexList.add(extTup1);
-        
-        
-        ValidIndexCombinationGenerator vic = new 
ValidIndexCombinationGenerator(pq1.getTupleExpr());
-        Iterator<List<ExternalTupleSet>> combos = 
vic.getValidIndexCombos(indexList);
-        int size = 0;
-        while(combos.hasNext()) {
-            combos.hasNext();
-            size++;
-            combos.next();
-            combos.hasNext();
-        }
-        
-       Assert.assertTrue(!combos.hasNext());
-       Assert.assertEquals(1,size);
-        
-        
-    }
-    
-    
-    
-    
-    
-    
-    @Test
-    public void medQueryEightOverlapIndex() {
-        String q1 = ""//
-                + "SELECT ?f ?m ?d " //
-                + "{" //
-                + "  ?f a ?m ."//
-                + "  ?m <http://www.w3.org/2000/01/rdf-schema#label> ?d ."//
-                + "  ?d <uri:talksTo> ?f . "//
-                + "  ?f <uri:hangOutWith> ?m ." //
-                + "  ?m <uri:hangOutWith> ?d ." //
-                + "  ?f <uri:associatesWith> ?m ." //
-                + "  ?m <uri:associatesWith> ?d ." //
-                + "}";//
-        
-        
-        String q2 = ""//
-                + "SELECT ?t ?s ?u " //
-                + "{" //
-                + "  ?s a ?t ."//
-                + "  ?t <http://www.w3.org/2000/01/rdf-schema#label> ?u ."//
-                + "  ?u <uri:talksTo> ?s . "//
-                + "}";//
-        
-        
-        String q3 = ""//
-                + "SELECT ?s ?t ?u " //
-                + "{" //
-                + "  ?s <uri:hangOutWith> ?t ." //
-                + "  ?t <uri:hangOutWith> ?u ." //
-                + "}";//
-        
-        String q4 = ""//
-                + "SELECT ?s ?t ?u " //
-                + "{" //
-                + "  ?s <uri:associatesWith> ?t ." //
-                + "  ?t <uri:associatesWith> ?u ." //
-                + "}";//
-        
-        
-        String q5 = ""//
-                + "SELECT ?t ?s ?u " //
-                + "{" //
-                + "  ?s a ?t ."//
-                + "  ?t <http://www.w3.org/2000/01/rdf-schema#label> ?u ."//
-                + "  ?u <uri:talksTo> ?s . "//
-                + "  ?s <uri:hangOutWith> ?t ." //
-                + "  ?t <uri:hangOutWith> ?u ." //
-                + "}";//
-        
-        String q6 = ""//
-                + "SELECT ?s ?t ?u " //
-                + "{" //
-                + "  ?s <uri:associatesWith> ?t ." //
-                + "  ?t <uri:associatesWith> ?u ." //
-                + "  ?s <uri:hangOutWith> ?t ." //
-                + "  ?t <uri:hangOutWith> ?u ." //
-                + "}";//
-        
-        
-        String q7 = ""//
-                + "SELECT ?s ?t ?u " //
-                + "{" //
-                + "  ?s <uri:associatesWith> ?t ." //
-                + "  ?t <uri:associatesWith> ?u ." //
-                + "  ?t <uri:hangOutWith> ?u ." //
-                + "}";//
-        
-        
-        
-        String q8 = ""//
-                + "SELECT ?t ?s ?u " //
-                + "{" //
-                + "  ?s a ?t ."//
-                + "  ?t <http://www.w3.org/2000/01/rdf-schema#label> ?u ."//
-                + "  ?u <uri:talksTo> ?s . "//
-                + "  ?s <uri:associatesWith> ?t ." //
-                + "}";//
-        
-        
-        String q9 = ""//
-                + "SELECT ?t ?s ?u " //
-                + "{" //
-                + "  ?s a ?t ."//
-                + "  ?t <http://www.w3.org/2000/01/rdf-schema#label> ?u ."//
-                + "}";//
-        
-        
-        
-        
-        
-        
-        
-        
-
-        SPARQLParser parser = new SPARQLParser();
-        ParsedQuery pq1 = null;
-        ParsedQuery pq2 = null;
-        ParsedQuery pq3 = null;
-        ParsedQuery pq4 = null;
-        ParsedQuery pq5 = null;
-        ParsedQuery pq6 = null;
-        ParsedQuery pq7 = null;
-        ParsedQuery pq8 = null;
-        ParsedQuery pq9 = null;
-        
-        SimpleExternalTupleSet extTup1 = null;
-        SimpleExternalTupleSet extTup2 = null;
-        SimpleExternalTupleSet extTup3 = null;
-        SimpleExternalTupleSet extTup4 = null;
-        SimpleExternalTupleSet extTup5 = null;
-        SimpleExternalTupleSet extTup6 = null;
-        SimpleExternalTupleSet extTup7 = null;
-        SimpleExternalTupleSet extTup8 = null;
-        
-        
-        
-        
-        
-        try {
-            pq1 = parser.parseQuery(q1, null);
-            pq2 = parser.parseQuery(q2, null);
-            pq3 = parser.parseQuery(q3, null);
-            pq4 = parser.parseQuery(q4, null);
-            pq5 = parser.parseQuery(q5, null);
-            pq6 = parser.parseQuery(q6, null);
-            pq7 = parser.parseQuery(q7, null);
-            pq8 = parser.parseQuery(q8, null);
-            pq9 = parser.parseQuery(q9, null);
-           
-
-            extTup1 = new SimpleExternalTupleSet((Projection) 
pq2.getTupleExpr());
-            extTup2 = new SimpleExternalTupleSet((Projection) 
pq3.getTupleExpr());
-            extTup3 = new SimpleExternalTupleSet((Projection) 
pq4.getTupleExpr());
-            extTup4 = new SimpleExternalTupleSet((Projection) 
pq5.getTupleExpr());
-            extTup5 = new SimpleExternalTupleSet((Projection) 
pq6.getTupleExpr());
-            extTup6 = new SimpleExternalTupleSet((Projection) 
pq7.getTupleExpr());
-            extTup7 = new SimpleExternalTupleSet((Projection) 
pq8.getTupleExpr());
-            extTup8 = new SimpleExternalTupleSet((Projection) 
pq9.getTupleExpr());
-            
-          
-        } catch (MalformedQueryException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        
-        List<ExternalTupleSet> indexList = Lists.newArrayList();
-        indexList.add(extTup1);
-        indexList.add(extTup2);
-        indexList.add(extTup3);
-        indexList.add(extTup4);
-        indexList.add(extTup5);
-        indexList.add(extTup6);
-        indexList.add(extTup7);
-        indexList.add(extTup8);
-        
-        
-        ValidIndexCombinationGenerator vic = new 
ValidIndexCombinationGenerator(pq1.getTupleExpr());
-        Iterator<List<ExternalTupleSet>> combos = 
vic.getValidIndexCombos(indexList);
-        int size = 0;
-        while(combos.hasNext()) {
-            combos.hasNext();
-            size++;
-            combos.next();
-            combos.hasNext();
-        }
-        
-       Assert.assertTrue(!combos.hasNext());
-       Assert.assertEquals(21,size);
-        
-        
-    }
-    
-    
-    
-    
-    
-    @Test
-    public void largeQuerySixteenIndexTest() {
-        
-        
-        String q1 = ""//
-                + "SELECT ?f ?m ?d ?e ?l ?c ?n ?o ?p ?a ?h ?r " //
-                + "{" //
-                + "  ?f a ?m ."//
-                + "  ?e a ?l ."//
-                + "  ?n a ?o ."//
-                + "  ?a a ?h ."//
-                + "  ?m <http://www.w3.org/2000/01/rdf-schema#label> ?d ."//
-                + "  ?l <http://www.w3.org/2000/01/rdf-schema#label> ?c ."//
-                + "  ?o <http://www.w3.org/2000/01/rdf-schema#label> ?p ."//
-                + "  ?h <http://www.w3.org/2000/01/rdf-schema#label> ?r ."//
-                + "  ?d <uri:talksTo> ?f . "//
-                + "  ?c <uri:talksTo> ?e . "//
-                + "  ?p <uri:talksTo> ?n . "//
-                + "  ?r <uri:talksTo> ?a . "//
-                + "}";//
-        
-        
-        String q2 = ""//
-                + "SELECT ?s ?t ?u " //
-                + "{" //
-                + "  ?s a ?t ."//
-                + "  ?t <http://www.w3.org/2000/01/rdf-schema#label> ?u ."//
-                + "  ?u <uri:talksTo> ?s . "//
-                + "}";//
-        
-        
-        
-        String q3 = ""//
-                + "SELECT  ?s ?t ?u ?d ?f ?g " //
-                + "{" //
-                + "  ?s a ?t ."//
-                + "  ?t <http://www.w3.org/2000/01/rdf-schema#label> ?u ."//
-                + "  ?u <uri:talksTo> ?s . "//
-                + "  ?d a ?f ."//
-                + "  ?f <http://www.w3.org/2000/01/rdf-schema#label> ?g ."//
-                + "  ?g <uri:talksTo> ?d . "//
-                + "}";//
-        
-     
-        
-        
-        SPARQLParser parser = new SPARQLParser();
-
-        ParsedQuery pq1 = null;
-        ParsedQuery pq2 = null;
-        ParsedQuery pq3 = null;
-       
-
-        try {
-            pq1 = parser.parseQuery(q1, null);
-            pq2 = parser.parseQuery(q2, null);
-            pq3 = parser.parseQuery(q3, null);
-          
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-        SimpleExternalTupleSet extTup1 = new 
SimpleExternalTupleSet((Projection) pq2.getTupleExpr());
-        SimpleExternalTupleSet extTup2 = new 
SimpleExternalTupleSet((Projection) pq3.getTupleExpr());
-       
-     
-        List<ExternalTupleSet> list = new ArrayList<ExternalTupleSet>();
-
-        list.add(extTup2);
-        list.add(extTup1);
-      
-
-        IndexedExecutionPlanGenerator iep = new 
IndexedExecutionPlanGenerator(pq1.getTupleExpr(), list);
-        List<ExternalTupleSet> indexSet = iep.getNormalizedIndices();
-        
-        
-        Assert.assertEquals(16, indexSet.size());
-        
-        ValidIndexCombinationGenerator vic = new 
ValidIndexCombinationGenerator(pq1.getTupleExpr());
-        Iterator<List<ExternalTupleSet>> eSet = 
vic.getValidIndexCombos(Lists.newArrayList(indexSet));
-        
-        int size = 0;
-        while(eSet.hasNext()) {
-            size++;
-            Assert.assertTrue(eSet.hasNext());
-            eSet.next();
-        }
-        
-        
-        Assert.assertTrue(!eSet.hasNext());
-        Assert.assertEquals(75, size);
-        
-    }
-    
-    
-    
-    
-    
-    
-    @Test
-    public void largeQueryFourtyIndexTest() {
-        
-        
-        String q1 = ""//
-                + "SELECT ?f ?m ?d ?e ?l ?c ?n ?o ?p ?a ?h ?r " //
-                + "{" //
-                + "  ?f a ?m ."//
-                + "  ?e a ?l ."//
-                + "  ?n a ?o ."//
-                + "  ?a a ?h ."//
-                + "  ?m <http://www.w3.org/2000/01/rdf-schema#label> ?d ."//
-                + "  ?l <http://www.w3.org/2000/01/rdf-schema#label> ?c ."//
-                + "  ?o <http://www.w3.org/2000/01/rdf-schema#label> ?p ."//
-                + "  ?h <http://www.w3.org/2000/01/rdf-schema#label> ?r ."//
-                + "  ?d <uri:talksTo> ?f . "//
-                + "  ?c <uri:talksTo> ?e . "//
-                + "  ?p <uri:talksTo> ?n . "//
-                + "  ?r <uri:talksTo> ?a . "//
-                + "}";//
-        
-        
-        String q2 = ""//
-                + "SELECT ?s ?t ?u " //
-                + "{" //
-                + "  ?s a ?t ."//
-                + "  ?t <http://www.w3.org/2000/01/rdf-schema#label> ?u ."//
-                + "  ?u <uri:talksTo> ?s . "//
-                + "}";//
-        
-        
-        
-        String q3 = ""//
-                + "SELECT  ?s ?t ?u ?d ?f ?g " //
-                + "{" //
-                + "  ?s a ?t ."//
-                + "  ?t <http://www.w3.org/2000/01/rdf-schema#label> ?u ."//
-                + "  ?u <uri:talksTo> ?s . "//
-                + "  ?d a ?f ."//
-                + "  ?f <http://www.w3.org/2000/01/rdf-schema#label> ?g ."//
-                + "  ?g <uri:talksTo> ?d . "//
-                + "}";//
-        
-        
-        
-        String q4 = ""//
-                + "SELECT  ?s ?t ?u ?d ?f ?g ?a ?b ?c" //
-                + "{" //
-                + "  ?s a ?t ."//
-                + "  ?t <http://www.w3.org/2000/01/rdf-schema#label> ?u ."//
-                + "  ?u <uri:talksTo> ?s . "//
-                + "  ?d a ?f ."//
-                + "  ?f <http://www.w3.org/2000/01/rdf-schema#label> ?g ."//
-                + "  ?g <uri:talksTo> ?d . "//
-                + "  ?a a ?b ."//
-                + "  ?b <http://www.w3.org/2000/01/rdf-schema#label> ?c ."//
-                + "  ?c <uri:talksTo> ?a . "//
-                + "}";//
-        
-        
-        SPARQLParser parser = new SPARQLParser();
-
-        ParsedQuery pq1 = null;
-        ParsedQuery pq2 = null;
-        ParsedQuery pq3 = null;
-        ParsedQuery pq4 = null;
-       
-
-        try {
-            pq1 = parser.parseQuery(q1, null);
-            pq2 = parser.parseQuery(q2, null);
-            pq3 = parser.parseQuery(q3, null);
-            pq4 = parser.parseQuery(q4, null);
-           
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-        SimpleExternalTupleSet extTup1 = new 
SimpleExternalTupleSet((Projection) pq2.getTupleExpr());
-        SimpleExternalTupleSet extTup2 = new 
SimpleExternalTupleSet((Projection) pq3.getTupleExpr());
-        SimpleExternalTupleSet extTup3 = new 
SimpleExternalTupleSet((Projection) pq4.getTupleExpr());
-     
-        List<ExternalTupleSet> list = new ArrayList<ExternalTupleSet>();
-
-        list.add(extTup2);
-        list.add(extTup1);
-        list.add(extTup3);
-
-        IndexedExecutionPlanGenerator iep = new 
IndexedExecutionPlanGenerator(pq1.getTupleExpr(), list);
-        List<ExternalTupleSet> indexSet = iep.getNormalizedIndices();
-        Assert.assertEquals(40, indexSet.size());
-        
-        ValidIndexCombinationGenerator vic = new 
ValidIndexCombinationGenerator(pq1.getTupleExpr());
-        Iterator<List<ExternalTupleSet>> eSet = 
vic.getValidIndexCombos(Lists.newArrayList(indexSet));
-        
-        int size = 0;
-        while(eSet.hasNext()) {
-            size++;
-            Assert.assertTrue(eSet.hasNext());
-            eSet.next();
-        }
-        
-        Assert.assertTrue(!eSet.hasNext());
-        Assert.assertEquals(123, size);
-    }
-    
-    
-    
-    
-    
-    
-    
-    
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/IndexPlanValidator/IndexPlanValidatorTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/IndexPlanValidator/IndexPlanValidatorTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/IndexPlanValidator/IndexPlanValidatorTest.java
index 30dafa2..ffd6691 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/IndexPlanValidator/IndexPlanValidatorTest.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/IndexPlanValidator/IndexPlanValidatorTest.java
@@ -41,7 +41,7 @@ public class IndexPlanValidatorTest {
 
        @Test
        public void testEvaluateTwoIndexTwoVarOrder1()
-                       throws MalformedQueryException {
+                       throws Exception {
 
 
                String indexSparqlString = ""//
@@ -93,7 +93,7 @@ public class IndexPlanValidatorTest {
 
        @Test
        public void testEvaluateTwoIndexTwoVarOrder2()
-                       throws MalformedQueryException {
+                       throws Exception {
 
 
                String indexSparqlString = ""//
@@ -146,7 +146,7 @@ public class IndexPlanValidatorTest {
 
        @Test
        public void testEvaluateTwoIndexTwoVarOrder3()
-                       throws MalformedQueryException {
+                       throws Exception {
 
 
                String indexSparqlString = ""//
@@ -199,7 +199,7 @@ public class IndexPlanValidatorTest {
 
        @Test
        public void testEvaluateTwoIndexTwoVarOrder4()
-                       throws MalformedQueryException {
+                       throws Exception {
 
 
                String indexSparqlString = ""//
@@ -253,7 +253,7 @@ public class IndexPlanValidatorTest {
 
        @Test
        public void testEvaluateTwoIndexTwoVarOrder6()
-                       throws MalformedQueryException {
+                       throws Exception {
 
 
                String indexSparqlString = ""//
@@ -306,7 +306,7 @@ public class IndexPlanValidatorTest {
 
        @Test
        public void testEvaluateTwoIndexCrossProduct1()
-                       throws MalformedQueryException {
+                       throws Exception {
 
 
                String indexSparqlString = ""//
@@ -358,7 +358,7 @@ public class IndexPlanValidatorTest {
 
        @Test
        public void testEvaluateTwoIndexCrossProduct2()
-                       throws MalformedQueryException {
+                       throws Exception {
 
 
                String indexSparqlString = ""//
@@ -411,7 +411,7 @@ public class IndexPlanValidatorTest {
 
        @Test
        public void testEvaluateTwoIndexCrossProduct3()
-                       throws MalformedQueryException {
+                       throws Exception {
 
 
                String indexSparqlString = ""//
@@ -463,7 +463,7 @@ public class IndexPlanValidatorTest {
        }
 
        @Test
-       public void testEvaluateTwoIndexDiffVars() throws 
MalformedQueryException {
+       public void testEvaluateTwoIndexDiffVars() throws Exception {
 
 
                String indexSparqlString = ""//
@@ -515,7 +515,7 @@ public class IndexPlanValidatorTest {
        }
 
        @Test
-       public void testEvaluateTwoIndexDiffVars2() throws 
MalformedQueryException {
+       public void testEvaluateTwoIndexDiffVars2() throws Exception {
 
 
                String indexSparqlString = ""//
@@ -567,7 +567,7 @@ public class IndexPlanValidatorTest {
        }
 
        @Test
-       public void testEvaluateTwoIndexDiffVars3() throws 
MalformedQueryException {
+       public void testEvaluateTwoIndexDiffVars3() throws Exception {
 
 
                String indexSparqlString = ""//
@@ -620,7 +620,7 @@ public class IndexPlanValidatorTest {
 
        @Test
        public void testEvaluateTwoIndexDiffVarsDirProd()
-                       throws MalformedQueryException {
+                       throws Exception {
 
 
                String indexSparqlString = ""//

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/external/AccumuloPcjIntegrationTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/external/AccumuloPcjIntegrationTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/external/AccumuloPcjIntegrationTest.java
index 21c5b94..e51cea1 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/external/AccumuloPcjIntegrationTest.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/external/AccumuloPcjIntegrationTest.java
@@ -1215,11 +1215,7 @@ public class AccumuloPcjIntegrationTest {
        }
 
        @Test
-       public void testEvaluateTwoIndexValidate() throws PcjException,
-                       RepositoryException, AccumuloException, 
AccumuloSecurityException,
-                       TableExistsException, TableNotFoundException,
-                       TupleQueryResultHandlerException, 
QueryEvaluationException,
-                       MalformedQueryException, SailException {
+       public void testEvaluateTwoIndexValidate() throws Exception {
 
                final URI superclass = new URIImpl("uri:superclass");
                final URI superclass2 = new URIImpl("uri:superclass2");
@@ -1289,11 +1285,7 @@ public class AccumuloPcjIntegrationTest {
        }
 
        @Test
-       public void testEvaluateThreeIndexValidate() throws PcjException,
-                       RepositoryException, AccumuloException, 
AccumuloSecurityException,
-                       TableExistsException, TableNotFoundException,
-                       MalformedQueryException, SailException, 
QueryEvaluationException,
-                       TupleQueryResultHandlerException {
+       public void testEvaluateThreeIndexValidate() throws Exception {
 
                final URI superclass = new URIImpl("uri:superclass");
                final URI superclass2 = new URIImpl("uri:superclass2");

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/external/PrecompJoinOptimizerTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/external/PrecompJoinOptimizerTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/external/PrecompJoinOptimizerTest.java
index 39f4a3a..e9ef3a2 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/external/PrecompJoinOptimizerTest.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/external/PrecompJoinOptimizerTest.java
@@ -300,7 +300,7 @@ public class PrecompJoinOptimizerTest {
        }
 
        @Test
-       public void twoFourIndexWithFilterTest() {
+       public void twoFourIndexWithFilterTest() throws Exception {
 
                final String q1 = ""//
                                + "SELECT ?f ?m ?d ?e ?l ?c " //

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerTest.java
index 0806349..bfea4ae 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerTest.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerTest.java
@@ -21,7 +21,6 @@ package org.apache.rya.indexing.mongo;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.apache.rya.accumulo.AccumuloRdfConfiguration;
 import org.apache.rya.api.domain.RyaStatement;
 import org.apache.rya.api.domain.RyaType;
 import org.apache.rya.api.domain.RyaURI;
@@ -50,14 +49,14 @@ import info.aduna.iteration.CloseableIteration;
 public class MongoFreeTextIndexerTest extends MongoRyaTestBase {
     private static final StatementConstraints EMPTY_CONSTRAINTS = new 
StatementConstraints();
 
-    AccumuloRdfConfiguration conf;
+    MongoDBRdfConfiguration conf;
 
     @Before
     public void before() throws Exception {
-        conf = new AccumuloRdfConfiguration();
+        conf = new MongoDBRdfConfiguration();
         conf.set(ConfigUtils.USE_MONGO, "true");
-        conf.set(MongoDBRdfConfiguration.MONGO_DB_NAME, "test");
-        conf.set(MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX, "rya_");
+        conf.setMongoDBName("test");
+        conf.setCollectionName("rya_");
         conf.setTablePrefix("another_");
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/FlattenedOptionalTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/FlattenedOptionalTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/FlattenedOptionalTest.java
index 4dbe9b6..8f2cb8c 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/FlattenedOptionalTest.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/FlattenedOptionalTest.java
@@ -20,6 +20,7 @@ package org.apache.rya.indexing.pcj.matching;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.rya.indexing.external.matching.FlattenedOptional;
 import org.junit.Assert;
 import org.junit.Test;
 import org.openrdf.query.MalformedQueryException;

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/JoinSegmentPCJMatcherTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/JoinSegmentPCJMatcherTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/JoinSegmentPCJMatcherTest.java
index 403ffae..8e61840 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/JoinSegmentPCJMatcherTest.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/JoinSegmentPCJMatcherTest.java
@@ -23,9 +23,10 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.rya.indexing.external.matching.ExternalSetMatcher;
+import org.apache.rya.indexing.external.matching.QuerySegmentFactory;
 import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
 import org.apache.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
-
 import org.junit.Assert;
 import org.junit.Test;
 import org.openrdf.query.MalformedQueryException;
@@ -42,7 +43,9 @@ import org.openrdf.query.parser.sparql.SPARQLParser;
 
 public class JoinSegmentPCJMatcherTest {
 
-
+    private final PCJExternalSetMatcherFactory pcjFactory = new 
PCJExternalSetMatcherFactory();
+    private final QuerySegmentFactory<ExternalTupleSet> qFactory = new 
QuerySegmentFactory<ExternalTupleSet>();
+    
        @Test
        public void testBasicSegment() throws MalformedQueryException {
 
@@ -69,11 +72,11 @@ public class JoinSegmentPCJMatcherTest {
                Projection proj = (Projection) te1;
                Join join = (Join) proj.getArg();
 
-               JoinSegmentPCJMatcher jsm = new JoinSegmentPCJMatcher(join);
+               ExternalSetMatcher<ExternalTupleSet> jsm = 
pcjFactory.getMatcher(qFactory.getQuerySegment(join));
                SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
-               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               Assert.assertEquals(true, jsm.match(pcj));
                TupleExpr te = jsm.getQuery();
-               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgs());
+               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgNodes());
 
                Set<QueryModelNode> qNodes = QueryNodeGatherer.getNodes(te);
                List<QueryModelNode> nodes = jsm.getOrderedNodes();
@@ -116,11 +119,11 @@ public class JoinSegmentPCJMatcherTest {
                Projection proj = (Projection) te1;
                Filter filter = (Filter) proj.getArg();
 
-               JoinSegmentPCJMatcher jsm = new JoinSegmentPCJMatcher(filter);
+               ExternalSetMatcher<ExternalTupleSet> jsm = 
pcjFactory.getMatcher(qFactory.getQuerySegment(filter));
                SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
-               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               Assert.assertEquals(true, jsm.match(pcj));
                TupleExpr te = jsm.getQuery();
-               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgs());
+               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgNodes());
 
                Set<QueryModelNode> qNodes = QueryNodeGatherer.getNodes(te);
                List<QueryModelNode> nodes = jsm.getOrderedNodes();
@@ -136,61 +139,6 @@ public class JoinSegmentPCJMatcherTest {
 
 
 
-       @Test
-       public void testWithUnmatchedNodes() throws Exception {
-
-               String query1 = ""//
-                               + "SELECT ?e ?c ?l" //
-                               + "{" //
-                               + " Filter(?e = <uri:Bob>)" //
-                               + " Filter(?c = <uri:Lawyer>)" //
-                               + " ?l <uri:workAt> <uri:Company1> ."
-                               + " OPTIONAL { ?e 
<http://www.w3.org/2000/01/rdf-schema#label> ?l } . "//
-                               + "  ?e a ?c . "//
-                               + "  ?e <uri:talksTo> ?l  . "//
-                               + "}";//
-
-               String query2 = ""//
-                               + "SELECT ?e ?c ?l" //
-                               + "{" //
-                               + " Filter(?e = <uri:Bob>)" //
-                               + " ?e a ?c . "//
-                               + " ?e <uri:talksTo> ?l . "//
-                               + "}";//
-
-               SPARQLParser parser = new SPARQLParser();
-               ParsedQuery pq1 = parser.parseQuery(query1, null);
-               ParsedQuery pq2 = parser.parseQuery(query2, null);
-               TupleExpr te1 = pq1.getTupleExpr();
-               TupleExpr te2 = pq2.getTupleExpr();
-               Projection proj = (Projection) te1;
-               Join join = (Join) proj.getArg();
-
-               JoinSegmentPCJMatcher jsm = new JoinSegmentPCJMatcher(join);
-               SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
-               Assert.assertEquals(true, jsm.matchPCJ(pcj));
-               TupleExpr te = jsm.getQuery();
-
-
-               Set<QueryModelNode> qNodes = QueryNodeGatherer.getNodes(te);
-               List<QueryModelNode> nodes = jsm.getOrderedNodes();
-               Set<QueryModelNode> nodeSet = new HashSet<>();
-               nodeSet.add(nodes.get(0));
-               nodeSet.add(nodes.get(1));
-               nodeSet.add(pcj);
-
-               Assert.assertEquals(1, jsm.getUnmatchedArgs().size());
-               Assert.assertEquals(true, 
jsm.getUnmatchedArgs().contains(nodes.get(1)));
-
-               Assert.assertEquals(nodeSet, new 
HashSet<QueryModelNode>(nodes));
-               Assert.assertEquals(nodeSet, qNodes);
-
-       }
-
-
-
-
-
        static class QueryNodeGatherer extends 
QueryModelVisitorBase<RuntimeException> {
 
                private static Set<QueryModelNode> nodes;

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/JoinSegmentTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/JoinSegmentTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/JoinSegmentTest.java
index e4afdac..71b24fc 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/JoinSegmentTest.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/JoinSegmentTest.java
@@ -23,8 +23,11 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.apache.rya.indexing.external.matching.QuerySegmentFactory;
+import org.apache.rya.indexing.external.matching.TopOfQueryFilterRelocator;
+import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
 import org.apache.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
-
 import org.junit.Assert;
 import org.junit.Test;
 import org.openrdf.query.MalformedQueryException;
@@ -38,6 +41,7 @@ import org.openrdf.query.parser.sparql.SPARQLParser;
 
 public class JoinSegmentTest {
 
+    private final QuerySegmentFactory<ExternalTupleSet> qFactory = new 
QuerySegmentFactory<ExternalTupleSet>();
 
        @Test
        public void testBasicSegment() throws MalformedQueryException {
@@ -65,8 +69,9 @@ public class JoinSegmentTest {
                Join join1 = (Join) ((Projection) te1).getArg();
                Join join2 = (Join) ((Projection) te2).getArg();
 
-               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
-               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+               
+               QuerySegment<ExternalTupleSet> seg1 = 
qFactory.getQuerySegment(join1);
+               QuerySegment<ExternalTupleSet> seg2 = 
qFactory.getQuerySegment(join2);
 
                Assert.assertEquals(true, seg1.containsQuerySegment(seg2));
                Assert.assertEquals(join1, seg1.getQuery().getTupleExpr());
@@ -75,7 +80,7 @@ public class JoinSegmentTest {
                SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
                List<QueryModelNode> nodes = seg1.getOrderedNodes();
                QueryModelNode node = nodes.get(0);
-               seg1.replaceWithPcj(seg2, pcj);
+               seg1.replaceWithExternalSet(seg2, pcj);
 
                Set<QueryModelNode> nodeSet = new HashSet<>();
                nodeSet.add(node);
@@ -116,8 +121,9 @@ public class JoinSegmentTest {
                Filter filter1 = (Filter) ((Projection) te1).getArg();
                Filter filter2 = (Filter) ((Projection) te2).getArg();
 
-               OptionalJoinSegment seg1 = new OptionalJoinSegment(filter1);
-               OptionalJoinSegment seg2 = new OptionalJoinSegment(filter2);
+               QuerySegment<ExternalTupleSet> seg1 = 
qFactory.getQuerySegment(filter1);
+        QuerySegment<ExternalTupleSet> seg2 = 
qFactory.getQuerySegment(filter2);
+
 
                Assert.assertEquals(filter1, seg1.getQuery().getTupleExpr());
                Assert.assertEquals(filter2, seg2.getQuery().getTupleExpr());
@@ -126,7 +132,7 @@ public class JoinSegmentTest {
                SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
                List<QueryModelNode> nodes = seg1.getOrderedNodes();
                QueryModelNode node = nodes.get(3);
-               seg1.replaceWithPcj(seg2, pcj);
+               seg1.replaceWithExternalSet(seg2, pcj);
 
                Set<QueryModelNode> nodeSet = new HashSet<>();
                nodeSet.add(node);
@@ -168,8 +174,9 @@ public class JoinSegmentTest {
                Filter filter1 = (Filter) ((Projection) te1).getArg();
                Filter filter2 = (Filter) ((Projection) te2).getArg();
 
-               OptionalJoinSegment seg1 = new OptionalJoinSegment(filter1);
-               OptionalJoinSegment seg2 = new OptionalJoinSegment(filter2);
+               QuerySegment<ExternalTupleSet> seg1 = 
qFactory.getQuerySegment(filter1);
+        QuerySegment<ExternalTupleSet> seg2 = 
qFactory.getQuerySegment(filter2);
+
 
                Assert.assertEquals(false, seg1.containsQuerySegment(seg2));
 
@@ -205,8 +212,8 @@ public class JoinSegmentTest {
                Join join1 = (Join) ((Projection) te1).getArg();
                Join join2 = (Join) ((Projection) te2).getArg();
 
-               OptionalJoinSegment seg1 = new OptionalJoinSegment(join1);
-               OptionalJoinSegment seg2 = new OptionalJoinSegment(join2);
+               QuerySegment<ExternalTupleSet> seg1 = 
qFactory.getQuerySegment(join1);
+        QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(join2);
 
                Assert.assertEquals(false, seg2.containsQuerySegment(seg1));
 

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/OptionalJoinSegmentPCJMatcherTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/OptionalJoinSegmentPCJMatcherTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/OptionalJoinSegmentPCJMatcherTest.java
index 64ab931..5064572 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/OptionalJoinSegmentPCJMatcherTest.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/OptionalJoinSegmentPCJMatcherTest.java
@@ -23,9 +23,11 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.rya.indexing.external.matching.ExternalSetMatcher;
+import org.apache.rya.indexing.external.matching.FlattenedOptional;
+import org.apache.rya.indexing.external.matching.QuerySegmentFactory;
 import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
 import org.apache.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
-
 import org.junit.Assert;
 import org.junit.Test;
 import org.openrdf.query.MalformedQueryException;
@@ -44,6 +46,10 @@ import org.openrdf.query.parser.sparql.SPARQLParser;
 public class OptionalJoinSegmentPCJMatcherTest {
 
 
+    private final PCJExternalSetMatcherFactory pcjFactory = new 
PCJExternalSetMatcherFactory();
+    private final QuerySegmentFactory<ExternalTupleSet> qFactory = new 
QuerySegmentFactory<ExternalTupleSet>();
+    
+    
        @Test
        public void testBasicSegment() throws MalformedQueryException {
 
@@ -70,11 +76,12 @@ public class OptionalJoinSegmentPCJMatcherTest {
                Projection proj = (Projection) te1;
                Join join = (Join) proj.getArg();
 
-               OptionalJoinSegmentPCJMatcher jsm = new 
OptionalJoinSegmentPCJMatcher(join);
+               
+               ExternalSetMatcher<ExternalTupleSet> jsm = 
pcjFactory.getMatcher(qFactory.getQuerySegment(join));
                SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
-               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               Assert.assertEquals(true, jsm.match(pcj));
                TupleExpr te = jsm.getQuery();
-               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgs());
+               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgNodes());
 
                Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
                List<QueryModelNode> nodes = jsm.getOrderedNodes();
@@ -117,11 +124,11 @@ public class OptionalJoinSegmentPCJMatcherTest {
                Projection proj = (Projection) te1;
                Filter filter = (Filter) proj.getArg();
 
-               OptionalJoinSegmentPCJMatcher jsm = new 
OptionalJoinSegmentPCJMatcher(filter);
+               ExternalSetMatcher<ExternalTupleSet> jsm = 
pcjFactory.getMatcher(qFactory.getQuerySegment(filter));
                SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
-               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               Assert.assertEquals(true, jsm.match(pcj));
                TupleExpr te = jsm.getQuery();
-               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgs());
+               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgNodes());
 
                Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
                List<QueryModelNode> nodes = jsm.getOrderedNodes();
@@ -167,11 +174,11 @@ public class OptionalJoinSegmentPCJMatcherTest {
                Projection proj = (Projection) te1;
                Join join = (Join) proj.getArg();
 
-               OptionalJoinSegmentPCJMatcher jsm = new 
OptionalJoinSegmentPCJMatcher(join);
+               ExternalSetMatcher<ExternalTupleSet> jsm = 
pcjFactory.getMatcher(qFactory.getQuerySegment(join));
                SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
-               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               Assert.assertEquals(true, jsm.match(pcj));
                TupleExpr te = jsm.getQuery();
-               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgs());
+               Assert.assertEquals(new HashSet<QueryModelNode>(), 
jsm.getUnmatchedArgNodes());
 
                Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
                List<QueryModelNode> nodes = jsm.getOrderedNodes();
@@ -220,15 +227,15 @@ public class OptionalJoinSegmentPCJMatcherTest {
                Projection proj = (Projection) te1;
                Join join = (Join) proj.getArg();
 
-               OptionalJoinSegmentPCJMatcher jsm = new 
OptionalJoinSegmentPCJMatcher(join);
+               ExternalSetMatcher<ExternalTupleSet> jsm = 
pcjFactory.getMatcher(qFactory.getQuerySegment(join));
                SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
-               Assert.assertEquals(true, jsm.matchPCJ(pcj));
+               Assert.assertEquals(true, jsm.match(pcj));
                TupleExpr te = jsm.getQuery();
                Set<QueryModelNode> qNodes = 
LeftJoinQueryNodeGatherer.getNodes(te);
                List<QueryModelNode> nodes = jsm.getOrderedNodes();
 
-               Assert.assertEquals(1, jsm.getUnmatchedArgs().size());
-               Assert.assertEquals(true, 
jsm.getUnmatchedArgs().contains(nodes.get(3)));
+               Assert.assertEquals(1, jsm.getUnmatchedArgNodes().size());
+               Assert.assertEquals(true, 
jsm.getUnmatchedArgNodes().contains(nodes.get(3)));
 
                Set<QueryModelNode> nodeSet = new HashSet<>();
                nodeSet.add(nodes.get(0));
@@ -283,11 +290,5 @@ public class OptionalJoinSegmentPCJMatcherTest {
                public void meet(Union node) {
                        nodes.add(node);
                }
-
-
        }
-
-
-
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/OptionalJoinSegmentTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/OptionalJoinSegmentTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/OptionalJoinSegmentTest.java
index 846e353..2a9d12a 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/OptionalJoinSegmentTest.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/OptionalJoinSegmentTest.java
@@ -23,8 +23,11 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.apache.rya.indexing.external.matching.QuerySegmentFactory;
+import org.apache.rya.indexing.external.matching.TopOfQueryFilterRelocator;
+import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
 import org.apache.rya.indexing.external.tupleSet.SimpleExternalTupleSet;
-
 import org.junit.Assert;
 import org.junit.Test;
 import org.openrdf.query.MalformedQueryException;
@@ -39,7 +42,7 @@ import org.openrdf.query.parser.sparql.SPARQLParser;
 
 public class OptionalJoinSegmentTest {
 
-
+    private final QuerySegmentFactory<ExternalTupleSet> qFactory = new 
QuerySegmentFactory<ExternalTupleSet>();
 
        @Test
        public void testBasicOptional() throws MalformedQueryException {
@@ -67,8 +70,9 @@ public class OptionalJoinSegmentTest {
                Join join = (Join) ((Projection) te1).getArg();
                LeftJoin lj = (LeftJoin) ((Projection) te2).getArg();
 
-               OptionalJoinSegment seg1 = new OptionalJoinSegment(join);
-               OptionalJoinSegment seg2 = new OptionalJoinSegment(lj);
+               QuerySegment<ExternalTupleSet> seg1 = 
qFactory.getQuerySegment(join);
+        QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(lj);
+
 
                Assert.assertEquals(true, seg1.containsQuerySegment(seg2));
                Assert.assertEquals(join, seg1.getQuery().getTupleExpr());
@@ -76,7 +80,7 @@ public class OptionalJoinSegmentTest {
                SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
                List<QueryModelNode> nodes = seg1.getOrderedNodes();
                QueryModelNode node = nodes.get(0);
-               seg1.replaceWithPcj(seg2, pcj);
+               seg1.replaceWithExternalSet(seg2, pcj);
 
                Set<QueryModelNode> nodeSet = new HashSet<>();
                nodeSet.add(node);
@@ -116,8 +120,8 @@ public class OptionalJoinSegmentTest {
                Filter filter1 = (Filter) ((Projection) te1).getArg();
                Filter filter2 = (Filter) ((Projection) te2).getArg();
 
-               OptionalJoinSegment seg1 = new OptionalJoinSegment(filter1);
-               OptionalJoinSegment seg2 = new OptionalJoinSegment(filter2);
+               QuerySegment<ExternalTupleSet> seg1 = 
qFactory.getQuerySegment(filter1);
+        QuerySegment<ExternalTupleSet> seg2 = 
qFactory.getQuerySegment(filter2);
 
                Assert.assertEquals(filter1, seg1.getQuery().getTupleExpr());
                Assert.assertEquals(true, seg1.containsQuerySegment(seg2));
@@ -125,7 +129,7 @@ public class OptionalJoinSegmentTest {
                SimpleExternalTupleSet pcj = new 
SimpleExternalTupleSet((Projection)te2);
                List<QueryModelNode> nodes = seg1.getOrderedNodes();
                QueryModelNode node = nodes.get(3);
-               seg1.replaceWithPcj(seg2, pcj);
+               seg1.replaceWithExternalSet(seg2, pcj);
 
                Set<QueryModelNode> nodeSet = new HashSet<>();
                nodeSet.add(node);


Reply via email to