You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2015/02/12 14:01:33 UTC

[07/77] [partial] incubator-tinkerpop git commit: moved com/tinkerpop directories to org/apache/tinkerpop

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/PartitionStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/PartitionStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/PartitionStrategy.java
new file mode 100644
index 0000000..7538c84
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/PartitionStrategy.java
@@ -0,0 +1,322 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.process.Step;
+import com.tinkerpop.gremlin.process.Traverser;
+import com.tinkerpop.gremlin.process.graph.traversal.GraphTraversal;
+import com.tinkerpop.gremlin.process.graph.traversal.step.filter.HasStep;
+import com.tinkerpop.gremlin.process.graph.traversal.DefaultGraphTraversal;
+import com.tinkerpop.gremlin.process.graph.util.HasContainer;
+import com.tinkerpop.gremlin.process.traverser.util.DefaultTraverserGeneratorFactory;
+import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import com.tinkerpop.gremlin.structure.Contains;
+import com.tinkerpop.gremlin.structure.Direction;
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Element;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+import com.tinkerpop.gremlin.structure.util.ElementHelper;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.util.StreamFactory;
+import com.tinkerpop.gremlin.util.function.TriFunction;
+import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+/**
+ * A {@link GraphStrategy} which enables support for logical graph partitioning where the Graph can be blinded to
+ * different parts of the total {@link com.tinkerpop.gremlin.structure.Graph}.  Note that the {@code partitionKey}
+ * is hidden by this strategy.  Use the base {@link com.tinkerpop.gremlin.structure.Graph} to access that.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Joshua Shinavier (http://fortytwo.net)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class PartitionStrategy implements GraphStrategy {
+
+    private String writePartition;
+    private final String partitionKey;
+    private final Set<String> readPartitions = new HashSet<>();
+
+    private PartitionStrategy(final String partitionKey, final String partition) {
+        this.writePartition = partition;
+        this.addReadPartition(partition);
+        this.partitionKey = partitionKey;
+    }
+
+    public String getWritePartition() {
+        return this.writePartition;
+    }
+
+    public void setWritePartition(final String writePartition) {
+        this.writePartition = writePartition;
+    }
+
+    public String getPartitionKey() {
+        return this.partitionKey;
+    }
+
+    public Set<String> getReadPartitions() {
+        return Collections.unmodifiableSet(this.readPartitions);
+    }
+
+    public void removeReadPartition(final String readPartition) {
+        this.readPartitions.remove(readPartition);
+    }
+
+    public void addReadPartition(final String readPartition) {
+        this.readPartitions.add(readPartition);
+    }
+
+    public void clearReadPartitions() {
+        this.readPartitions.clear();
+    }
+
+    ///////////// old subgraph strategy methods
+    @Override
+    public UnaryOperator<BiFunction<Direction, String[], Iterator<Vertex>>> getVertexIteratorsVertexIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (direction, labels) -> StreamFactory
+                .stream(ctx.getCurrent().getBaseVertex().iterators().edgeIterator(direction, labels))
+                .filter(this::testEdge)
+                .map(edge -> otherVertex(direction, ctx.getCurrent(), edge)).iterator();
+        // TODO: Note that we are not doing f.apply() like the other methods. Is this bad?
+        // by not calling f.apply() to get the iterator, we're possibly bypassing strategy methods that
+        // could have been sequenced
+    }
+
+    @Override
+    public UnaryOperator<BiFunction<Direction, String[], Iterator<Edge>>> getVertexIteratorsEdgeIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (direction, labels) -> IteratorUtils.filter(f.apply(direction, labels), this::testEdge);
+    }
+
+    @Override
+    public UnaryOperator<Function<Direction, Iterator<Vertex>>> getEdgeIteratorsVertexIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> direction -> IteratorUtils.filter(f.apply(direction), this::testVertex);
+    }
+
+    @Override
+    public UnaryOperator<Function<Object[], GraphTraversal<Vertex, Vertex>>> getGraphVStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> ids -> {
+            final GraphTraversal<Vertex, Vertex> traversal = this.generateTraversal(ctx.getStrategyGraph().getBaseGraph().getClass());
+            traversal.asAdmin().getStrategies().setTraverserGeneratorFactory(DefaultTraverserGeneratorFactory.instance());
+            TraversalHelper.insertTraversal(0, f.apply(ids).has(this.partitionKey, Contains.within, getReadPartitions()).asAdmin(), traversal.asAdmin());
+            return traversal.filter(vertex -> testVertex(vertex.get()));
+        };
+    }
+
+    @Override
+    public UnaryOperator<Function<Object[], GraphTraversal<Edge, Edge>>> getGraphEStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> ids -> {
+            final GraphTraversal<Edge, Edge> traversal = this.generateTraversal(ctx.getStrategyGraph().getBaseGraph().getClass());
+            traversal.asAdmin().getStrategies().setTraverserGeneratorFactory(DefaultTraverserGeneratorFactory.instance());
+            TraversalHelper.insertTraversal(0, f.apply(ids).has(this.partitionKey, Contains.within, getReadPartitions()).asAdmin(), traversal.asAdmin());
+            return traversal.filter(edge -> testEdge(edge.get()));
+        };
+    }
+
+    private boolean testElement(final Element element) {
+        final Property<String> property = element instanceof StrategyElement ?
+                ((StrategyElement) element).getBaseElement().property(this.partitionKey) :
+                element.property(this.partitionKey);
+        return property.isPresent() && this.readPartitions.contains(property.value());
+    }
+
+    private boolean testVertex(final Vertex vertex) {
+        return testElement(vertex);
+    }
+
+    private boolean testEdge(final Edge edge) {
+        // the edge must pass the edge predicate, and both of its incident vertices must also pass the vertex predicate
+        // inV() and/or outV() will be empty if they do not.  it is sometimes the case that an edge is unwrapped
+        // in which case it may not be filtered.  in such cases, the vertices on such edges should be tested.
+        return testElement(edge)
+                && (edge instanceof StrategyWrapped ? edge.iterators().vertexIterator(Direction.IN).hasNext() && edge.iterators().vertexIterator(Direction.OUT).hasNext()
+                : testVertex(edge.iterators().vertexIterator(Direction.IN).next()) && testVertex(edge.iterators().vertexIterator(Direction.OUT).next()));
+    }
+
+    private static final Vertex otherVertex(final Direction direction, final Vertex start, final Edge edge) {
+        if (direction.equals(Direction.BOTH)) {
+            final Vertex inVertex = edge.iterators().vertexIterator(Direction.IN).next();
+            return ElementHelper.areEqual(start, inVertex) ?
+                    edge.iterators().vertexIterator(Direction.OUT).next() :
+                    inVertex;
+        } else {
+            return edge.iterators().vertexIterator(direction.opposite()).next();
+        }
+    }
+
+    private final <S, E> GraphTraversal<S, E> generateTraversal(final Class emanatingClass) {
+        return new DefaultGraphTraversal<S, E>(emanatingClass) {
+            @Override
+            public GraphTraversal<S, Vertex> to(final Direction direction, final String... edgeLabels) {
+                return direction.equals(Direction.BOTH) ?
+                        this.toE(direction, edgeLabels).otherV() :
+                        this.toE(direction, edgeLabels).toV(direction.opposite());
+            }
+
+            @Override
+            public GraphTraversal<S, Edge> toE(final Direction direction, final String... edgeLabels) {
+                return super.toE(direction, edgeLabels).has(getPartitionKey(), Contains.within, getReadPartitions()).filter(edge -> testEdge(edge.get()));
+            }
+
+            @Override
+            public GraphTraversal<S, Vertex> toV(final Direction direction) {
+                return super.toV(direction).has(getPartitionKey(), Contains.within, getReadPartitions());
+            }
+
+            @Override
+            public GraphTraversal<S, Vertex> otherV() {
+                return super.otherV().has(getPartitionKey(), Contains.within, getReadPartitions());
+            }
+
+            @Override
+            public GraphTraversal<S, E> has(final String key, final BiPredicate predicate, final Object value) {
+                final HasContainer hasContainer = new HasContainer(key, predicate, value);
+                final HasStep<Element> hasStep = new HasStep(this, hasContainer) {
+                    @Override
+                    protected boolean filter(final Traverser.Admin traverser) {
+                        return hasContainer.test(((StrategyElement) traverser.get()).getBaseElement());
+                    }
+                };
+                return this.asAdmin().addStep((Step) hasStep);
+            }
+        };
+    }
+
+    ///////////////////////////
+
+    @Override
+    public <V> UnaryOperator<Function<String[], Iterator<VertexProperty<V>>>> getVertexIteratorsPropertyIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (keys) -> IteratorUtils.filter(f.apply(keys), property -> {
+            return !this.partitionKey.equals(property.key());
+        });
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String[], Iterator<V>>> getVertexIteratorsValueIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (keys) -> IteratorUtils.map(ctx.getCurrent().iterators().<V>propertyIterator(keys), vertexProperty -> vertexProperty.value());
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Set<String>>> getVertexKeysStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> () -> IteratorUtils.fill(IteratorUtils.filter(f.get().iterator(), key -> {
+            return !this.partitionKey.equals(key);
+        }), new HashSet<>());
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String, VertexProperty<V>>> getVertexGetPropertyStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> k -> {
+            return k.equals(this.partitionKey) ? VertexProperty.<V>empty() : f.apply(k);
+        };
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String, Property<V>>> getEdgeGetPropertyStrategy(StrategyContext<StrategyEdge> ctx, GraphStrategy composingStrategy) {
+        return (f) -> k -> {
+            return k.equals(this.partitionKey) ? Property.<V>empty() : f.apply(k);
+        };
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String[], Iterator<Property<V>>>> getEdgeIteratorsPropertyIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (keys) -> IteratorUtils.filter(f.apply(keys), property -> {
+            return !this.partitionKey.equals(property.key());
+        });
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String[], Iterator<V>>> getEdgeIteratorsValueIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (keys) -> IteratorUtils.map(ctx.getCurrent().iterators().<V>propertyIterator(keys), property -> property.value());
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Set<String>>> getEdgeKeysStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> () -> IteratorUtils.fill(IteratorUtils.filter(f.get().iterator(), key -> {
+            return !this.partitionKey.equals(key);
+        }), new HashSet<>());
+    }
+
+    @Override
+    public UnaryOperator<Function<Object[], Vertex>> getAddVertexStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (keyValues) -> f.apply(this.addKeyValues(keyValues));
+    }
+
+    @Override
+    public UnaryOperator<TriFunction<String, Vertex, Object[], Edge>> getAddEdgeStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (label, v, keyValues) -> f.apply(label, v, this.addKeyValues(keyValues));
+    }
+
+    private final Object[] addKeyValues(final Object[] keyValues) {
+        final Object[] keyValuesExtended = Arrays.copyOf(keyValues, keyValues.length + 2);
+        keyValuesExtended[keyValues.length] = this.partitionKey;
+        keyValuesExtended[keyValues.length + 1] = this.writePartition;
+        return keyValuesExtended;
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.graphStrategyString(this);
+    }
+
+    public static Builder build() {
+        return new Builder();
+    }
+
+    public static class Builder {
+        private String startPartition = "default";
+        private String partitionKey = "_partition";
+
+        private Builder() {
+        }
+
+        /**
+         * The initial partition to filter by. If this value is not set, it will be defaulted to "default".
+         */
+        public Builder startPartition(final String startPartition) {
+            if (null == startPartition) throw new IllegalArgumentException("The startPartition cannot be null");
+            this.startPartition = startPartition;
+            return this;
+        }
+
+        /**
+         * The name of the partition key.  If this is not set, then the value is defaulted to "_partition".
+         */
+        public Builder partitionKey(final String partitionKey) {
+            if (null == partitionKey) throw new IllegalArgumentException("The partitionKey cannot be null");
+            this.partitionKey = partitionKey;
+            return this;
+        }
+
+        public PartitionStrategy create() {
+            return new PartitionStrategy(partitionKey, startPartition);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/ReadOnlyStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/ReadOnlyStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/ReadOnlyStrategy.java
new file mode 100644
index 0000000..d76085d
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/ReadOnlyStrategy.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.util.function.TriFunction;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+/**
+ * This {@link GraphStrategy} prevents the graph from being modified and will throw a
+ * {@link UnsupportedOperationException} if an attempt is made to do so.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public final class ReadOnlyStrategy implements GraphStrategy {
+    private static final ReadOnlyStrategy instance = new ReadOnlyStrategy();
+
+    private ReadOnlyStrategy() {
+    }
+
+    public static final ReadOnlyStrategy instance() {
+        return instance;
+    }
+
+    @Override
+    public UnaryOperator<Function<Object[], Vertex>> getAddVertexStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+        return readOnlyFunction();
+    }
+
+    @Override
+    public UnaryOperator<TriFunction<String, Vertex, Object[], Edge>> getAddEdgeStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return readOnlyTriFunction();
+    }
+
+    @Override
+    public <V> UnaryOperator<BiFunction<String, V, Property<V>>> getEdgePropertyStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (t, u) -> {
+            throw Exceptions.graphUsesReadOnlyStrategy();
+        };
+    }
+
+    @Override
+    public <V> UnaryOperator<BiFunction<String, V, VertexProperty<V>>> getVertexPropertyStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (t, u) -> {
+            throw Exceptions.graphUsesReadOnlyStrategy();
+        };
+    }
+
+    @Override
+    public <V, U> UnaryOperator<BiFunction<String, V, Property<V>>> getVertexPropertyPropertyStrategy(final StrategyContext<StrategyVertexProperty<U>> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (t, u) -> {
+            throw Exceptions.graphUsesReadOnlyStrategy();
+        };
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Void>> getRemoveEdgeStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return readOnlySupplier();
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Void>> getRemoveVertexStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return readOnlySupplier();
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<Void>> getRemovePropertyStrategy(final StrategyContext<StrategyProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return readOnlySupplier();
+    }
+
+    @Override
+    public UnaryOperator<BiConsumer<String, Object>> getVariableSetStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> (k, v) -> {
+            throw Exceptions.graphUsesReadOnlyStrategy();
+        };
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Map<String, Object>>> getVariableAsMapStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+        return (f) -> () -> Collections.unmodifiableMap(f.get());
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<Void>> getRemoveVertexPropertyStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return readOnlySupplier();
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.graphStrategyString(this);
+    }
+
+    public static <T> UnaryOperator<Supplier<T>> readOnlySupplier() {
+        return (f) -> () -> {
+            throw Exceptions.graphUsesReadOnlyStrategy();
+        };
+    }
+
+    public static <T, U> UnaryOperator<Function<T, U>> readOnlyFunction() {
+        return (f) -> (t) -> {
+            throw Exceptions.graphUsesReadOnlyStrategy();
+        };
+    }
+
+    public static <T, U, V, W> UnaryOperator<TriFunction<T, U, V, W>> readOnlyTriFunction() {
+        return (f) -> (t, u, v) -> {
+            throw Exceptions.graphUsesReadOnlyStrategy();
+        };
+    }
+
+    public static class Exceptions {
+        public static UnsupportedOperationException graphUsesReadOnlyStrategy() {
+            return new UnsupportedOperationException(String.format("Graph uses %s and is therefore unmodifiable", ReadOnlyStrategy.class));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/SequenceStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/SequenceStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/SequenceStrategy.java
new file mode 100644
index 0000000..64f472f
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/SequenceStrategy.java
@@ -0,0 +1,366 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.process.graph.traversal.GraphTraversal;
+import com.tinkerpop.gremlin.structure.Direction;
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+import com.tinkerpop.gremlin.util.function.TriFunction;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+import java.util.stream.Collectors;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class SequenceStrategy implements GraphStrategy {
+    private final List<GraphStrategy> graphStrategySequence;
+
+    private SequenceStrategy(final List<GraphStrategy> strategies) {
+        this.graphStrategySequence = strategies;
+    }
+
+    public List<GraphStrategy> getGraphStrategySequence() {
+        return Collections.unmodifiableList(graphStrategySequence);
+    }
+
+    @Override
+    public UnaryOperator<Function<Object[], Iterator<Vertex>>> getGraphIteratorsVertexIteratorStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getGraphIteratorsVertexIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Function<Object[], Iterator<Edge>>> getGraphIteratorsEdgeIteratorStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getGraphIteratorsEdgeIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Function<Object[], Vertex>> getAddVertexStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getAddVertexStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<TriFunction<String, Vertex, Object[], Edge>> getAddEdgeStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getAddEdgeStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Void>> getRemoveEdgeStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getRemoveEdgeStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Void>> getRemoveVertexStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getRemoveVertexStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<Void>> getRemovePropertyStrategy(final StrategyContext<StrategyProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getRemovePropertyStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String, VertexProperty<V>>> getVertexGetPropertyStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexGetPropertyStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String, Property<V>>> getEdgeGetPropertyStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getEdgeGetPropertyStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<BiFunction<String, V, VertexProperty<V>>> getVertexPropertyStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<BiFunction<String, V, Property<V>>> getEdgePropertyStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getEdgePropertyStrategy(ctx, this));
+    }
+
+    @Override
+    public <V, U> UnaryOperator<BiFunction<String, V, Property<V>>> getVertexPropertyPropertyStrategy(final StrategyContext<StrategyVertexProperty<U>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyPropertyStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Object>> getVertexIdStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexIdStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Graph>> getVertexGraphStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexGraphStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<Object>> getVertexPropertyIdStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyIdStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<Graph>> getVertexPropertyGraphStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyGraphStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Object>> getEdgeIdStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getEdgeIdStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Graph>> getEdgeGraphStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getEdgeGraphStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<String>> getVertexLabelStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexLabelStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<String>> getEdgeLabelStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getEdgeLabelStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<String>> getVertexPropertyLabelStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyLabelStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String[], Iterator<VertexProperty<V>>>> getVertexIteratorsPropertyIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexIteratorsPropertyIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String[], Iterator<Property<V>>>> getEdgeIteratorsPropertyIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getEdgeIteratorsPropertyIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public <V, U> UnaryOperator<Function<String[], Iterator<Property<V>>>> getVertexPropertyIteratorsPropertyIteratorStrategy(final StrategyContext<StrategyVertexProperty<U>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyIteratorsPropertyIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Set<String>>> getVertexKeysStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexKeysStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Set<String>>> getEdgeKeysStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getEdgeKeysStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<Set<String>>> getVertexPropertyKeysStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyKeysStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String[], Iterator<V>>> getVertexIteratorsValueIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexIteratorsValueIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String[], Iterator<V>>> getEdgeIteratorsValueIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getEdgeIteratorsValueIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public <V, U> UnaryOperator<Function<String[], Iterator<V>>> getVertexPropertyIteratorsValueIteratorStrategy(final StrategyContext<StrategyVertexProperty<U>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyIteratorsValueIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Function<Direction, Iterator<Vertex>>> getEdgeIteratorsVertexIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getEdgeIteratorsVertexIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<BiFunction<Direction, String[], Iterator<Vertex>>> getVertexIteratorsVertexIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexIteratorsVertexIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<BiFunction<Direction, String[], Iterator<Edge>>> getVertexIteratorsEdgeIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexIteratorsEdgeIteratorStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String, V>> getVertexValueStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexValueStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Function<String, V>> getEdgeValueStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getEdgeValueStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Set<String>>> getVariableKeysStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVariableKeysStrategy(ctx, this));
+    }
+
+    @Override
+    public <R> UnaryOperator<Function<String, Optional<R>>> getVariableGetStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVariableGetStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Consumer<String>> getVariableRemoveStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVariableRemoveStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<BiConsumer<String, Object>> getVariableSetStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVariableSetStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Map<String, Object>>> getVariableAsMapStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVariableAsMapStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Supplier<Void>> getGraphCloseStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getGraphCloseStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<Void>> getRemoveVertexPropertyStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getRemoveVertexPropertyStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<Vertex>> getVertexPropertyGetElementStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyGetElementStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Function<Object[], GraphTraversal<Vertex, Vertex>>> getGraphVStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getGraphVStrategy(ctx, this));
+    }
+
+    @Override
+    public UnaryOperator<Function<Object[], GraphTraversal<Edge, Edge>>> getGraphEStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getGraphEStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<V>> getVertexPropertyValueStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyValueStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<V>> getPropertyValueStrategy(final StrategyContext<StrategyProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getPropertyValueStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<String>> getVertexPropertyKeyStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyKeyStrategy(ctx, this));
+    }
+
+    @Override
+    public <V> UnaryOperator<Supplier<String>> getPropertyKeyStrategy(final StrategyContext<StrategyProperty<V>> ctx, final GraphStrategy composingStrategy) {
+        return this.composeStrategyUnaryOperator(s -> s.getPropertyKeyStrategy(ctx, this));
+    }
+
+    @Override
+    public String toString() {
+        return String.join("->", this.graphStrategySequence.stream().map(Object::toString)
+                .map(String::toLowerCase).collect(Collectors.<String>toList()));
+    }
+
+    /**
+     * Compute a new strategy function from the sequence of supplied {@link GraphStrategy} objects.
+     *
+     * @param f a {@link java.util.function.Function} that extracts a particular strategy implementation from a {@link GraphStrategy}
+     * @return a newly constructed {@link java.util.function.UnaryOperator} that applies each extracted strategy implementation in
+     * the order supplied
+     */
+    private UnaryOperator composeStrategyUnaryOperator(final Function<GraphStrategy, UnaryOperator> f) {
+        return this.graphStrategySequence.stream().map(f).reduce(null,
+                (acc, next) -> acc == null ? next : toUnaryOp(acc.compose(next)));
+    }
+
+    /**
+     * Converts a {@link java.util.function.Function} to a {@link java.util.function.UnaryOperator} since the call to
+     * {@link java.util.function.UnaryOperator#andThen(java.util.function.Function)} doesn't return {@link java.util.function.UnaryOperator} and can't
+     * be casted to one.
+     *
+     * @param f a {@link java.util.function.Function} that has the same argument and return type
+     * @return a {@link java.util.function.UnaryOperator} of the supplied {@code f}
+     */
+    private static <T> UnaryOperator<T> toUnaryOp(final Function<T, T> f) {
+        return new UnaryOperator<T>() {
+            @Override
+            public T apply(T t) {
+                return f.apply(t);
+            }
+        };
+    }
+
+    public static Builder build() {
+        return new Builder();
+    }
+
+    public static class Builder {
+        private List<GraphStrategy> strategies = new ArrayList<>();
+
+        private Builder() {
+            strategies.add(IdentityStrategy.instance());
+        }
+
+        /**
+         * Provide the sequence of {@link GraphStrategy} implementations to execute.  If this value is not set,
+         * then a {@code SequenceStrategy} is initialized with a single
+         * {@link com.tinkerpop.gremlin.structure.strategy.IdentityStrategy} instance.
+         */
+        public Builder sequence(final GraphStrategy... strategies) {
+            this.strategies = new ArrayList<>(Arrays.asList(strategies));
+            return this;
+        }
+
+        public SequenceStrategy create() {
+            return new SequenceStrategy(strategies);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyContext.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyContext.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyContext.java
new file mode 100644
index 0000000..ce78df1
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyContext.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Graph;
+
+/**
+ * The {@link StrategyContext} object is provided to the methods of {@link GraphStrategy} so that the strategy functions
+ * it constructs have some knowledge of the environment.
+ *
+ * @param <T> represents the object that is triggering the strategy (i.e. the vertex on which addEdge was called).
+ */
+public final class StrategyContext<T extends StrategyWrapped> {
+    private final StrategyGraph g;
+    private final T current;
+
+    public StrategyContext(final StrategyGraph g, final T current) {
+        if (null == g) throw Graph.Exceptions.argumentCanNotBeNull("g");
+        if (null == current) throw Graph.Exceptions.argumentCanNotBeNull("current");
+
+        this.g = g;
+        this.current = current;
+    }
+
+    /**
+     * Gets the {@link StrategyWrapped} instance that is triggering the {@link GraphStrategy} method.
+     */
+    public T getCurrent() {
+        return current;
+    }
+
+    /**
+     * Gets the current {@link com.tinkerpop.gremlin.structure.strategy.StrategyGraph} instance.
+     */
+    public StrategyGraph getStrategyGraph() {
+        return g;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyEdge.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyEdge.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyEdge.java
new file mode 100644
index 0000000..9517498
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyEdge.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Direction;
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedEdge;
+import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StrategyEdge extends StrategyElement implements Edge, Edge.Iterators, StrategyWrapped, WrappedEdge<Edge> {
+
+    private final StrategyContext<StrategyEdge> strategyContext;
+
+    public StrategyEdge(final Edge baseEdge, final StrategyGraph strategyGraph) {
+        super(baseEdge, strategyGraph);
+        this.strategyContext = new StrategyContext<>(strategyGraph, this);
+    }
+
+    @Override
+    public Edge.Iterators iterators() {
+        return this;
+    }
+
+    @Override
+    public Graph graph() {
+        return this.strategyGraph.compose(
+                s -> s.getEdgeGraphStrategy(this.strategyContext, strategy),
+                () -> this.strategyGraph).get();
+    }
+
+    @Override
+    public Object id() {
+        return this.strategyGraph.compose(
+                s -> s.getEdgeIdStrategy(this.strategyContext, strategy),
+                this.getBaseEdge()::id).get();
+    }
+
+    @Override
+    public String label() {
+        return this.strategyGraph.compose(
+                s -> s.getEdgeLabelStrategy(this.strategyContext, strategy),
+                this.getBaseEdge()::label).get();
+    }
+
+    @Override
+    public <V> V value(final String key) throws NoSuchElementException {
+        return this.strategyGraph.compose(
+                s -> s.<V>getEdgeValueStrategy(this.strategyContext, strategy),
+                this.getBaseEdge()::value).apply(key);
+    }
+
+    @Override
+    public Set<String> keys() {
+        return this.strategyGraph.compose(
+                s -> s.getEdgeKeysStrategy(this.strategyContext, strategy),
+                this.getBaseEdge()::keys).get();
+    }
+
+    @Override
+    public Edge getBaseEdge() {
+        return (Edge) this.baseElement;
+    }
+
+    @Override
+    public <V> Property<V> property(final String key) {
+        return new StrategyProperty<>(this.strategyGraph.compose(
+                s -> s.<V>getEdgeGetPropertyStrategy(this.strategyContext, strategy),
+                this.getBaseEdge()::property).apply(key), this.strategyGraph);
+    }
+
+    @Override
+    public <V> Property<V> property(final String key, final V value) {
+        return new StrategyProperty<>(this.strategyGraph.compose(
+                s -> s.<V>getEdgePropertyStrategy(this.strategyContext, strategy),
+                this.getBaseEdge()::property).apply(key, value), this.strategyGraph);
+    }
+
+    @Override
+    public void remove() {
+        this.strategyGraph.compose(
+                s -> s.getRemoveEdgeStrategy(this.strategyContext, strategy),
+                () -> {
+                    this.getBaseEdge().remove();
+                    return null;
+                }).get();
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.graphStrategyElementString(this);
+    }
+
+
+    @Override
+    public Iterator<Vertex> vertexIterator(final Direction direction) {
+        return new StrategyVertex.StrategyVertexIterator(this.strategyGraph.compose(
+                s -> s.getEdgeIteratorsVertexIteratorStrategy(this.strategyContext, strategy),
+                (Direction d) -> this.getBaseEdge().iterators().vertexIterator(d)).apply(direction), this.strategyGraph);
+    }
+
+    @Override
+    public <V> Iterator<V> valueIterator(final String... propertyKeys) {
+        return this.strategyGraph.compose(
+                s -> s.<V>getEdgeIteratorsValueIteratorStrategy(this.strategyContext, strategy),
+                (String[] pks) -> this.getBaseEdge().iterators().valueIterator(pks)).apply(propertyKeys);
+    }
+
+    @Override
+    public <V> Iterator<Property<V>> propertyIterator(final String... propertyKeys) {
+        return IteratorUtils.map(this.strategyGraph.compose(
+                        s -> s.<V>getEdgeIteratorsPropertyIteratorStrategy(this.strategyContext, strategy),
+                        (String[] pks) -> this.getBaseEdge().iterators().propertyIterator(pks)).apply(propertyKeys),
+                property -> new StrategyProperty<>(property, this.strategyGraph));
+    }
+
+
+    public static class StrategyEdgeIterator implements Iterator<Edge> {
+        private final Iterator<Edge> edges;
+        private final StrategyGraph strategyGraph;
+
+        public StrategyEdgeIterator(final Iterator<Edge> itty,
+                                    final StrategyGraph strategyGraph) {
+            this.edges = itty;
+            this.strategyGraph = strategyGraph;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return this.edges.hasNext();
+        }
+
+        @Override
+        public Edge next() {
+            return new StrategyEdge(this.edges.next(), this.strategyGraph);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyElement.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyElement.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyElement.java
new file mode 100644
index 0000000..46d8fed
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyElement.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Element;
+import com.tinkerpop.gremlin.structure.util.ElementHelper;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public abstract class StrategyElement implements Element, StrategyWrapped {
+    protected final StrategyGraph strategyGraph;
+    protected final GraphStrategy strategy;
+    protected final Element baseElement;
+    protected final StrategyContext<StrategyElement> elementStrategyContext;
+
+    protected StrategyElement(final Element baseElement, final StrategyGraph strategyGraph) {
+        if (baseElement instanceof StrategyWrapped) throw new IllegalArgumentException(
+                String.format("The element %s is already StrategyWrapped and must be a base Element", baseElement));
+        this.strategyGraph = strategyGraph;
+        this.strategy = strategyGraph.getStrategy();
+        this.baseElement = baseElement;
+        this.elementStrategyContext = new StrategyContext<>(strategyGraph, this);
+    }
+
+    public Element getBaseElement() {
+        return this.baseElement;
+    }
+
+    @Override
+    public int hashCode() {
+        return this.baseElement.hashCode();
+    }
+
+    @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
+    @Override
+    public boolean equals(final Object object) {
+        return ElementHelper.areEqual(this, object);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyGraph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyGraph.java
new file mode 100644
index 0000000..d80391e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyGraph.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.computer.GraphComputer;
+import com.tinkerpop.gremlin.process.graph.traversal.GraphTraversal;
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Transaction;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedGraph;
+import com.tinkerpop.gremlin.util.function.FunctionUtils;
+import org.apache.commons.configuration.Configuration;
+
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+/**
+ * A wrapper class for {@link Graph} instances that host and apply a {@link GraphStrategy}.  The wrapper implements
+ * {@link Graph} itself and intercepts calls made to the hosted instance and then applies the strategy.  Methods
+ * that return an extension of {@link com.tinkerpop.gremlin.structure.Element} or a
+ * {@link com.tinkerpop.gremlin.structure.Property} will be automatically wrapped in a {@link StrategyWrapped}
+ * implementation.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class StrategyGraph implements Graph, Graph.Iterators, StrategyWrapped, WrappedGraph<Graph> {
+    private final Graph baseGraph;
+    private final GraphStrategy strategy;
+    private final StrategyContext<StrategyGraph> graphContext;
+
+    public StrategyGraph(final Graph baseGraph) {
+        this(baseGraph, IdentityStrategy.instance());
+    }
+
+    public StrategyGraph(final Graph baseGraph, final GraphStrategy strategy) {
+        if (baseGraph instanceof StrategyWrapped) throw new IllegalArgumentException(
+                String.format("The graph %s is already StrategyWrapped and must be a base Graph", baseGraph));
+        if (null == strategy) throw new IllegalArgumentException("Strategy cannot be null");
+
+        this.strategy = strategy;
+        this.baseGraph = baseGraph;
+        this.graphContext = new StrategyContext<>(this, this);
+    }
+
+    /**
+     * Gets the underlying base {@link Graph} that is being hosted within this wrapper.
+     */
+    @Override
+    public Graph getBaseGraph() {
+        return this.baseGraph;
+    }
+
+    /**
+     * Gets the {@link com.tinkerpop.gremlin.structure.strategy.GraphStrategy} for the {@link com.tinkerpop.gremlin.structure.Graph}.
+     */
+    public GraphStrategy getStrategy() {
+        return this.strategy;
+    }
+
+    /**
+     * Return a {@link GraphStrategy} function that takes the base function of the form denoted by {@code T} as
+     * an argument and returns back a function with {@code T}.
+     *
+     * @param f    a function to execute if a {@link com.tinkerpop.gremlin.structure.strategy.GraphStrategy}.
+     * @param impl the base implementation of an operation.
+     * @return a function that will be applied in the Gremlin Structure implementation
+     */
+    public <T> T compose(final Function<GraphStrategy, UnaryOperator<T>> f, final T impl) {
+        return f.apply(this.strategy).apply(impl);
+    }
+
+    @Override
+    public Vertex addVertex(final Object... keyValues) {
+        final Optional<Vertex> v = Optional.ofNullable(compose(
+                s -> s.getAddVertexStrategy(this.graphContext, strategy),
+                this.baseGraph::addVertex).apply(keyValues));
+        return v.isPresent() ? new StrategyVertex(v.get(), this) : null;
+    }
+
+    @Override
+    public GraphTraversal<Vertex, Vertex> V(final Object... vertexIds) {
+        return this.compose(s -> s.getGraphVStrategy(this.graphContext, this.strategy), this.baseGraph::V).apply(vertexIds).map(vertex -> new StrategyVertex(vertex.get(), this));
+       /* final GraphTraversal<Vertex, Vertex> traversal = new DefaultGraphTraversal<>(this.getClass());
+        return traversal.asAdmin().addStep(new StrategyGraphStep<>(traversal, this, Vertex.class, this.compose(
+                s -> s.getGraphVStrategy(this.graphContext, strategy),
+                this.baseGraph::V).apply(vertexIds))); */
+    }
+
+    @Override
+    public GraphTraversal<Edge, Edge> E(final Object... edgeIds) {
+        return this.compose(s -> s.getGraphEStrategy(this.graphContext, this.strategy), this.baseGraph::E).apply(edgeIds).map(edge -> new StrategyEdge(edge.get(), this));
+        /*final GraphTraversal<Edge, Edge> traversal = new DefaultGraphTraversal<>(this.getClass());
+        return traversal.asAdmin().addStep(new StrategyGraphStep<>(traversal, this, Edge.class, this.compose(
+                s -> s.getGraphEStrategy(this.graphContext, strategy),
+                this.baseGraph::E).apply(edgeIds)));*/
+    }
+
+    @Override
+    public <T extends Traversal<S, S>, S> T of(final Class<T> traversalClass) {
+        return this.baseGraph.of(traversalClass);  // TODO: wrap the users traversal in StrategyWrappedTraversal
+    }
+
+    @Override
+    public GraphComputer compute(final Class... graphComputerClass) {
+        return this.baseGraph.compute(graphComputerClass);
+    }
+
+    @Override
+    public Transaction tx() {
+        return this.baseGraph.tx();
+    }
+
+    @Override
+    public Variables variables() {
+        return new StrategyVariables(this.baseGraph.variables(), this);
+    }
+
+    @Override
+    public Configuration configuration() {
+        return this.baseGraph.configuration();
+    }
+
+    @Override
+    public Features features() {
+        return this.baseGraph.features();
+    }
+
+    @Override
+    public Iterators iterators() {
+        return this;
+    }
+
+    @Override
+    public Iterator<Vertex> vertexIterator(final Object... vertexIds) {
+        return new StrategyVertex.StrategyVertexIterator(compose(s -> s.getGraphIteratorsVertexIteratorStrategy(this.graphContext, strategy), this.baseGraph.iterators()::vertexIterator).apply(vertexIds), this);
+    }
+
+    @Override
+    public Iterator<Edge> edgeIterator(final Object... edgeIds) {
+        return new StrategyEdge.StrategyEdgeIterator(compose(s -> s.getGraphIteratorsEdgeIteratorStrategy(this.graphContext, strategy), this.baseGraph.iterators()::edgeIterator).apply(edgeIds), this);
+    }
+
+    @Override
+    public void close() throws Exception {
+        // compose function doesn't seem to want to work here even though it works with other Supplier<Void>
+        // strategy functions. maybe the "throws Exception" is hosing it up.......
+        this.strategy.getGraphCloseStrategy(this.graphContext, strategy).apply(FunctionUtils.wrapSupplier(() -> {
+            baseGraph.close();
+            return null;
+        })).get();
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.graphStrategyString(strategy, this.baseGraph);
+    }
+
+    public static class Exceptions {
+        public static IllegalStateException strategyGraphIsSafe() {
+            return new IllegalStateException("StrategyGraph is in safe mode - its elements cannot be unwrapped.");
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyProperty.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyProperty.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyProperty.java
new file mode 100644
index 0000000..09d0c10
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyProperty.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Element;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedProperty;
+
+import java.util.NoSuchElementException;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StrategyProperty<V> implements Property<V>, StrategyWrapped, WrappedProperty<Property<V>> {
+
+    private final Property<V> baseProperty;
+    private final StrategyContext<StrategyProperty<V>> strategyContext;
+    private final StrategyGraph strategyGraph;
+    private final GraphStrategy strategy;
+
+    public StrategyProperty(final Property<V> baseProperty, final StrategyGraph strategyGraph) {
+        if (baseProperty instanceof StrategyWrapped) throw new IllegalArgumentException(
+                String.format("The property %s is already StrategyWrapped and must be a base Property", baseProperty));
+        this.baseProperty = baseProperty;
+        this.strategyContext = new StrategyContext<>(strategyGraph, this);
+        this.strategyGraph = strategyGraph;
+        this.strategy = strategyGraph.getStrategy();
+    }
+
+    @Override
+    public String key() {
+        return this.strategyGraph.compose(
+                s -> s.getPropertyKeyStrategy(this.strategyContext, strategy), this.baseProperty::key).get();
+    }
+
+    @Override
+    public V value() throws NoSuchElementException {
+        return this.strategyGraph.compose(
+                s -> s.getPropertyValueStrategy(this.strategyContext, strategy), this.baseProperty::value).get();
+    }
+
+    @Override
+    public boolean isPresent() {
+        return this.baseProperty.isPresent();
+    }
+
+    @Override
+    public Element element() {
+        final Element baseElement = this.baseProperty.element();
+        return (baseElement instanceof Vertex ? new StrategyVertex((Vertex) baseElement, this.strategyGraph) :
+                new StrategyEdge((Edge) baseElement, this.strategyGraph));
+    }
+
+    @Override
+    public <E extends Throwable> V orElseThrow(final Supplier<? extends E> exceptionSupplier) throws E {
+        return this.baseProperty.orElseThrow(exceptionSupplier);
+    }
+
+    @Override
+    public V orElseGet(final Supplier<? extends V> valueSupplier) {
+        return this.baseProperty.orElseGet(valueSupplier);
+    }
+
+    @Override
+    public V orElse(final V otherValue) {
+        return this.baseProperty.orElse(otherValue);
+    }
+
+    @Override
+    public void ifPresent(final Consumer<? super V> consumer) {
+        this.baseProperty.ifPresent(consumer);
+    }
+
+    @Override
+    public void remove() {
+        this.strategyGraph.compose(
+                s -> s.getRemovePropertyStrategy(strategyContext, strategy),
+                () -> {
+                    this.baseProperty.remove();
+                    return null;
+                }).get();
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.graphStrategyPropertyString(this);
+    }
+
+    @Override
+    public Property<V> getBaseProperty() {
+        return this.baseProperty;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVariables.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVariables.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVariables.java
new file mode 100644
index 0000000..f492389
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVariables.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedVariables;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StrategyVariables implements StrategyWrapped, Graph.Variables, WrappedVariables<Graph.Variables> {
+
+    protected final StrategyGraph strategyGraph;
+    private final Graph.Variables baseVariables;
+    private final StrategyContext<StrategyVariables> variableStrategyContext;
+    private final GraphStrategy strategy;
+
+    public StrategyVariables(final Graph.Variables variables, final StrategyGraph strategyGraph) {
+        if (variables instanceof StrategyWrapped) throw new IllegalArgumentException(
+                String.format("The variables %s is already StrategyWrapped and must be a base Variables", variables));
+        this.baseVariables = variables;
+        this.strategyGraph = strategyGraph;
+        this.variableStrategyContext = new StrategyContext<>(strategyGraph, this);
+        this.strategy = strategyGraph.getStrategy();
+    }
+
+    @Override
+    public Set<String> keys() {
+        return this.strategyGraph.compose(
+                s -> s.getVariableKeysStrategy(this.variableStrategyContext, strategy),
+                this.baseVariables::keys).get();
+    }
+
+    @Override
+    public <R> Optional<R> get(final String key) {
+        return this.strategyGraph.compose(
+                s -> s.<R>getVariableGetStrategy(this.variableStrategyContext, strategy),
+                this.baseVariables::get).apply(key);
+    }
+
+    @Override
+    public void set(final String key, final Object value) {
+        this.strategyGraph.compose(
+                s -> s.getVariableSetStrategy(this.variableStrategyContext, strategy),
+                this.baseVariables::set).accept(key, value);
+    }
+
+    @Override
+    public void remove(final String key) {
+        this.strategyGraph.compose(
+                s -> s.getVariableRemoveStrategy(this.variableStrategyContext, strategy),
+                this.baseVariables::remove).accept(key);
+    }
+
+    @Override
+    public Map<String, Object> asMap() {
+        return this.strategyGraph.compose(
+                s -> s.getVariableAsMapStrategy(this.variableStrategyContext, strategy),
+                this.baseVariables::asMap).get();
+    }
+
+    @Override
+    public Graph.Variables getBaseVariables() {
+        return this.baseVariables;
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.graphStrategyVariables(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertex.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertex.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertex.java
new file mode 100644
index 0000000..7276b10
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertex.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Direction;
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedVertex;
+import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class StrategyVertex extends StrategyElement implements Vertex, StrategyWrapped, WrappedVertex<Vertex>, Vertex.Iterators {
+
+    private final StrategyContext<StrategyVertex> strategyContext;
+
+    public StrategyVertex(final Vertex baseVertex, final StrategyGraph strategyGraph) {
+        super(baseVertex, strategyGraph);
+        this.strategyContext = new StrategyContext<>(strategyGraph, this);
+    }
+
+    @Override
+    public Graph graph() {
+        return this.strategyGraph.compose(
+                s -> s.getVertexGraphStrategy(this.strategyContext, strategy),
+                () -> this.strategyGraph).get();
+    }
+
+    @Override
+    public Object id() {
+        return this.strategyGraph.compose(
+                s -> s.getVertexIdStrategy(this.strategyContext, strategy),
+                this.getBaseVertex()::id).get();
+    }
+
+    @Override
+    public String label() {
+        return this.strategyGraph.compose(
+                s -> s.getVertexLabelStrategy(this.strategyContext, strategy),
+                this.getBaseVertex()::label).get();
+    }
+
+    @Override
+    public Set<String> keys() {
+        return this.strategyGraph.compose(
+                s -> s.getVertexKeysStrategy(this.strategyContext, strategy),
+                this.getBaseVertex()::keys).get();
+    }
+
+    @Override
+    public Vertex.Iterators iterators() {
+        return this;
+    }
+
+    @Override
+    public <V> V value(final String key) throws NoSuchElementException {
+        return this.strategyGraph.compose(
+                s -> s.<V>getVertexValueStrategy(this.strategyContext, strategy),
+                this.getBaseVertex()::value).apply(key);
+    }
+
+    @Override
+    public void remove() {
+        this.strategyGraph.compose(
+                s -> s.getRemoveVertexStrategy(this.strategyContext, strategy),
+                () -> {
+                    this.getBaseVertex().remove();
+                    return null;
+                }).get();
+    }
+
+    @Override
+    public Vertex getBaseVertex() {
+        return (Vertex) this.baseElement;
+    }
+
+    @Override
+    public Edge addEdge(final String label, final Vertex inVertex, final Object... keyValues) {
+        final Vertex baseInVertex = (inVertex instanceof StrategyVertex) ? ((StrategyVertex) inVertex).getBaseVertex() : inVertex;
+        return new StrategyEdge(this.strategyGraph.compose(
+                s -> s.getAddEdgeStrategy(this.strategyContext, strategy),
+                this.getBaseVertex()::addEdge)
+                .apply(label, baseInVertex, keyValues), this.strategyGraph);
+    }
+
+    @Override
+    public <V> VertexProperty<V> property(final String key, final V value) {
+        return new StrategyVertexProperty<>(this.strategyGraph.compose(
+                s -> s.<V>getVertexPropertyStrategy(this.strategyContext, strategy),
+                this.getBaseVertex()::property).apply(key, value), this.strategyGraph);
+    }
+
+    @Override
+    public <V> VertexProperty<V> property(final String key) {
+        return new StrategyVertexProperty<>(this.strategyGraph.compose(
+                s -> s.<V>getVertexGetPropertyStrategy(this.strategyContext, strategy),
+                this.getBaseVertex()::property).apply(key), this.strategyGraph);
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.graphStrategyElementString(this);
+    }
+
+    @Override
+    public Iterator<Edge> edgeIterator(final Direction direction, final String... edgeLabels) {
+        return new StrategyEdge.StrategyEdgeIterator(this.strategyGraph.compose(
+                s -> s.getVertexIteratorsEdgeIteratorStrategy(this.strategyContext, strategy),
+                (Direction d, String[] l) -> this.getBaseVertex().iterators().edgeIterator(d, l)).apply(direction, edgeLabels), this.strategyGraph);
+    }
+
+    @Override
+    public Iterator<Vertex> vertexIterator(final Direction direction, final String... labels) {
+        return new StrategyVertexIterator(this.strategyGraph.compose(
+                s -> s.getVertexIteratorsVertexIteratorStrategy(strategyContext, strategy),
+                (Direction d, String[] l) -> this.getBaseVertex().iterators().vertexIterator(d, l)).apply(direction, labels), this.strategyGraph);
+    }
+
+    @Override
+    public <V> Iterator<V> valueIterator(final String... propertyKeys) {
+        return this.strategyGraph.compose(
+                s -> s.<V>getVertexIteratorsValueIteratorStrategy(strategyContext, strategy),
+                (String[] pks) -> this.getBaseVertex().iterators().valueIterator(pks)).apply(propertyKeys);
+    }
+
+    @Override
+    public <V> Iterator<VertexProperty<V>> propertyIterator(final String... propertyKeys) {
+        return IteratorUtils.map(this.strategyGraph.compose(
+                        s -> s.<V>getVertexIteratorsPropertyIteratorStrategy(this.strategyContext, strategy),
+                        (String[] pks) -> this.getBaseVertex().iterators().propertyIterator(pks)).apply(propertyKeys),
+                property -> new StrategyVertexProperty<>(property, this.strategyGraph));
+    }
+
+    public static class StrategyVertexIterator implements Iterator<Vertex> {
+        private final Iterator<Vertex> vertices;
+        private final StrategyGraph strategyGraph;
+
+        public StrategyVertexIterator(final Iterator<Vertex> iterator, final StrategyGraph strategyGraph) {
+            this.vertices = iterator;
+            this.strategyGraph = strategyGraph;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return this.vertices.hasNext();
+        }
+
+        @Override
+        public Vertex next() {
+            return new StrategyVertex(this.vertices.next(), this.strategyGraph);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertexProperty.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertexProperty.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertexProperty.java
new file mode 100644
index 0000000..cf88a50
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertexProperty.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedVertexProperty;
+import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class StrategyVertexProperty<V> extends StrategyElement implements VertexProperty<V>, StrategyWrapped, WrappedVertexProperty<VertexProperty<V>>, VertexProperty.Iterators {
+
+    private final StrategyContext<StrategyVertexProperty<V>> strategyContext;
+
+    public StrategyVertexProperty(final VertexProperty<V> baseVertexProperty, final StrategyGraph strategyGraph) {
+        super(baseVertexProperty, strategyGraph);
+        this.strategyContext = new StrategyContext<>(strategyGraph, this);
+    }
+
+    @Override
+    public Graph graph() {
+        return this.strategyGraph.compose(
+                s -> s.getVertexPropertyGraphStrategy(strategyContext, strategy),
+                () -> this.strategyGraph).get();
+    }
+
+    @Override
+    public Object id() {
+        return this.strategyGraph.compose(
+                s -> s.getVertexPropertyIdStrategy(strategyContext, strategy),
+                this.getBaseVertexProperty()::id).get();
+    }
+
+    @Override
+    public String label() {
+        return this.strategyGraph.compose(
+                s -> s.getVertexPropertyLabelStrategy(strategyContext, strategy),
+                this.getBaseVertexProperty()::label).get();
+    }
+
+    @Override
+    public Set<String> keys() {
+        return this.strategyGraph.compose(
+                s -> s.getVertexPropertyKeysStrategy(strategyContext, strategy),
+                this.getBaseVertexProperty()::keys).get();
+    }
+
+    @Override
+    public Vertex element() {
+        return new StrategyVertex(this.strategyGraph.compose(
+                s -> s.getVertexPropertyGetElementStrategy(strategyContext, strategy),
+                this.getBaseVertexProperty()::element).get(), strategyGraph);
+    }
+
+    @Override
+    public VertexProperty.Iterators iterators() {
+        return this;
+    }
+
+    @Override
+    public <U> Property<U> property(final String key, final U value) {
+        return new StrategyProperty<>(this.strategyGraph.compose(
+                s -> s.<U, V>getVertexPropertyPropertyStrategy(strategyContext, strategy),
+                this.getBaseVertexProperty()::property).<String, U>apply(key, value), this.strategyGraph);
+    }
+
+    @Override
+    public String key() {
+        return this.strategyGraph.compose(
+                s -> s.getVertexPropertyKeyStrategy(this.strategyContext, strategy), this.getBaseVertexProperty()::key).get();
+    }
+
+    @Override
+    public V value() throws NoSuchElementException {
+        return this.strategyGraph.compose(
+                s -> s.getVertexPropertyValueStrategy(this.strategyContext, strategy), this.getBaseVertexProperty()::value).get();
+    }
+
+    @Override
+    public boolean isPresent() {
+        return this.getBaseVertexProperty().isPresent();
+    }
+
+    @Override
+    public void remove() {
+        this.strategyGraph.compose(
+                s -> s.getRemoveVertexPropertyStrategy(this.strategyContext, strategy),
+                () -> {
+                    this.getBaseVertexProperty().remove();
+                    return null;
+                }).get();
+    }
+
+    @Override
+    public VertexProperty<V> getBaseVertexProperty() {
+        return (VertexProperty<V>) this.baseElement;
+    }
+
+    @Override
+    public String toString() {
+        return StringFactory.graphStrategyElementString(this);
+    }
+
+
+    @Override
+    public <U> Iterator<Property<U>> propertyIterator(final String... propertyKeys) {
+        return IteratorUtils.map(this.strategyGraph.compose(
+                        s -> s.<U, V>getVertexPropertyIteratorsPropertyIteratorStrategy(this.strategyContext, strategy),
+                        (String[] pks) -> this.getBaseVertexProperty().iterators().propertyIterator(pks)).apply(propertyKeys),
+                property -> new StrategyProperty<>(property, this.strategyGraph));
+    }
+
+    @Override
+    public <U> Iterator<U> valueIterator(final String... propertyKeys) {
+        return this.strategyGraph.compose(
+                s -> s.<U, V>getVertexPropertyIteratorsValueIteratorStrategy(this.strategyContext, strategy),
+                (String[] pks) -> this.getBaseVertexProperty().iterators().valueIterator(pks)).apply(propertyKeys);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyWrapped.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyWrapped.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyWrapped.java
new file mode 100644
index 0000000..f967385
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyWrapped.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.tinkerpop.gremlin.structure.strategy;
+
+/**
+ * A marker interface for the graph wrapper classes.  Classes that are strategy wrappers should implement this
+ * interface.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public interface StrategyWrapped {
+}