package com.tinkerpop.gremlin.structure.strategy;

import com.tinkerpop.gremlin.process.Traversal;
import com.tinkerpop.gremlin.process.graph.GraphTraversal;
import com.tinkerpop.gremlin.process.computer.GraphComputer;
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 java.util.Optional;

/**
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
public class StrategyWrappedGraph implements Graph, StrategyWrapped {
    private final Graph baseGraph;
    protected Strategy strategy = new Strategy.Simple();
    private Strategy.Context<StrategyWrappedGraph> graphContext;

    public StrategyWrappedGraph(final Graph baseGraph) {
        this.baseGraph = baseGraph;
        this.graphContext = new Strategy.Context<>(baseGraph, this);
    }

    public Graph getBaseGraph() {
        return this.baseGraph;
    }

    public Strategy strategy() {
        return this.strategy;
    }

    @Override
    public Vertex addVertex(final Object... keyValues) {
        final Optional<Vertex> v = Optional.ofNullable(strategy.compose(
                s -> s.getAddVertexStrategy(graphContext),
                this.baseGraph::addVertex).apply(keyValues));
        return v.isPresent() ? new StrategyWrappedVertex(v.get(), this) : null;
    }

    @Override
    public Vertex v(final Object id) {
        return new StrategyWrappedVertex(strategy().compose(
                s -> s.getGraphvStrategy(graphContext),
                this.baseGraph::v).apply(id), this);
    }

    @Override
    public Edge e(final Object id) {
        return new StrategyWrappedEdge(strategy().compose(
                s -> s.getGrapheStrategy(graphContext),
                this.baseGraph::e).apply(id), this);
    }

    @Override
    public GraphTraversal<Vertex, Vertex> V() {
        return applyStrategy(baseGraph.V());
    }

    @Override
    public GraphTraversal<Edge, Edge> E() {
        return applyStrategy(baseGraph.E());
    }

    @Override
    public <T extends Traversal> T traversal(final Class<T> traversalClass) {
        return this.baseGraph.traversal(traversalClass);
    }

    @Override
    public <C extends GraphComputer> C compute(final Class<C>... graphComputerClass) {
        return this.baseGraph.compute(graphComputerClass);
    }

    @Override
    public Transaction tx() {
        return this.baseGraph.tx();
    }

    @Override
    public Variables variables() {
        return this.baseGraph.variables();
    }

    @Override
    public Features getFeatures() {
        return this.baseGraph.getFeatures();
    }

    @Override
    public void close() throws Exception {
        this.baseGraph.close();
    }

	@Override
	public String toString() {
		final GraphStrategy strategy = this.strategy.getGraphStrategy().orElse(GraphStrategy.DoNothingGraphStrategy.INSTANCE);
		return String.format("[%s[%s]]", strategy, baseGraph.toString());
	}

    private <S,E> GraphTraversal<S,E> applyStrategy(final GraphTraversal<S,E> traversal) {
        traversal.strategies().register(new StrategyWrappedTraversalStrategy(this));
        this.strategy.getGraphStrategy().ifPresent(s -> s.applyStrategyToTraversal(traversal));
        return traversal;
    }
}

@@ -435,16 +435,462 @@
 l;%0A%0A/**%0A
+ * A wrapper class for %7B@link Graph%7D instances that host and apply a %7B@link GraphStrategy%7D.  The wrapper implements%0A * %7B@link Graph%7D itself and intercepts calls made to the hosted instance and then applies the strategy.  Methods%0A * that return an extension of %7B@link com.tinkerpop.gremlin.structure.Element%7D or a%0A * %7B@link com.tinkerpop.gremlin.structure.Property%7D will be automatically wrapped in a %7B@link StrategyWrapped%7D%0A * implementation.%0A *%0A
  * @auth
@@ -940,16 +940,16 @@
 me.com)%0A
-
  */%0Apubl
@@ -1333,32 +1333,136 @@
 , this);%0A    %7D%0A%0A
+    /**%0A     * Gets the underlying base %7B@link Graph%7D that is being hosted within this wrapper.%0A     */%0A
     public Graph
@@ -1513,24 +1513,92 @@
 aph;%0A    %7D%0A%0A
+    /**%0A     * Gets the strategy hosted within the wrapper.%0A     */%0A
     public S

Add javadoc.