You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2016/02/11 20:45:12 UTC

[06/15] incubator-tinkerpop git commit: Added lots of JavaDoc. Lots of organization and clean up. Ready for PR.

Added lots of JavaDoc. Lots of organization and clean up. Ready for PR.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/229474ab
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/229474ab
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/229474ab

Branch: refs/heads/master
Commit: 229474ab17a20de9be93325f8d170d915f60414a
Parents: 908433f
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Feb 9 07:29:08 2016 -0700
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Feb 9 07:29:08 2016 -0700

----------------------------------------------------------------------
 .../process/traversal/TraversalSource.java      | 126 ++++++++++++++++++-
 .../traversal/TraversalSourceFactory.java       |  46 -------
 .../dsl/graph/GraphTraversalSource.java         |  58 +++++----
 .../traversal/step/util/RequirementsStep.java   |  55 ++++++++
 .../decoration/RequirementsStrategy.java        |  59 +++++++++
 .../strategy/decoration/SackStrategy.java       |  38 +++++-
 .../traversal/util/TraversalScriptFunction.java |   1 -
 .../traversal/util/TraversalSourceFactory.java  |  52 ++++++++
 .../gremlin/groovy/loaders/StepLoader.groovy    |  19 ++-
 .../gremlin/groovy/loaders/SugarLoader.groovy   |  37 +-----
 10 files changed, 366 insertions(+), 125 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/229474ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
index 3b684a2..08badfa 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
@@ -20,16 +20,20 @@ package org.apache.tinkerpop.gremlin.process.traversal;
 
 import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
 import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier;
 
 import java.io.Serializable;
+import java.util.function.BinaryOperator;
 import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
 
 /**
  * A {@code TraversalSource} is used to create {@link Traversal} instances.
  * A traversal source can generate any number of {@link Traversal} instances.
  * A traversal source is primarily composed of a {@link Graph} and a {@link TraversalStrategies}.
- * Various {@code withXXX}-based methods are used to configure the traversal strategies.
- * Various other methods (dependent on the traversal source type) will then generate a traversal given the graph and configured strategies.
+ * Various {@code withXXX}-based methods are used to configure the traversal strategies (called "configurations").
+ * Various other methods (dependent on the traversal source type) will then generate a traversal given the graph and configured strategies (called "spawns").
  * A traversal source is immutable in that fluent chaining of configurations create new traversal sources.
  * This is unlike {@link Traversal} and {@link GraphComputer}, where chained methods configure the same instance.
  * Every traversal source implementation must maintain two constructors to enable proper reflection-based construction.
@@ -73,7 +77,7 @@ public interface TraversalSource extends Cloneable {
      * @return a new traversal source with updated strategies
      */
     public default TraversalSource withComputer(final Class<? extends GraphComputer> graphComputerClass) {
-        return this.withComputer(g -> g.compute(graphComputerClass));
+        return this.withComputer(graph -> graph.compute(graphComputerClass));
     }
 
     /**
@@ -104,6 +108,122 @@ public interface TraversalSource extends Cloneable {
     public TraversalSource withoutStrategies(final Class<? extends TraversalStrategy>... traversalStrategyClasses);
 
     /**
+     * Add a sideEffect to be used throughout the life of a spawned {@link Traversal}.
+     * This adds a {@link org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SideEffectStrategy} to the strategies.
+     *
+     * @param key          the key of the sideEffect
+     * @param initialValue a supplier that produces the initial value of the sideEffect
+     * @return a new traversal source with updated strategies
+     */
+    public TraversalSource withSideEffect(final String key, final Supplier initialValue);
+
+    /**
+     * Add a sideEffect to be used throughout the life of a spawned {@link Traversal}.
+     * This adds a {@link org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SideEffectStrategy} to the strategies.
+     *
+     * @param key          the key of the sideEffect
+     * @param initialValue the initial value of the sideEffect
+     * @return a new traversal source with updated strategies
+     */
+    public default TraversalSource withSideEffect(final String key, final Object initialValue) {
+        return this.withSideEffect(key, new ConstantSupplier<>(initialValue));
+    }
+
+    /**
+     * Add a sack to be used throughout the life of a spawned {@link Traversal}.
+     * This adds a {@link org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SackStrategy} to the strategies.
+     *
+     * @param initialValue  a supplier that produces the initial value of the sideEffect
+     * @param splitOperator the sack split operator
+     * @param mergeOperator the sack merge operator
+     * @return a new traversal source with updated strategies
+     */
+    public <A> TraversalSource withSack(final Supplier<A> initialValue, final UnaryOperator<A> splitOperator, final BinaryOperator<A> mergeOperator);
+
+    /**
+     * Add a sack to be used throughout the life of a spawned {@link Traversal}.
+     * This adds a {@link org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SackStrategy} to the strategies.
+     *
+     * @param initialValue  the initial value of the sideEffect
+     * @param splitOperator the sack split operator
+     * @param mergeOperator the sack merge operator
+     * @return a new traversal source with updated strategies
+     */
+    public default <A> TraversalSource withSack(final A initialValue, final UnaryOperator<A> splitOperator, final BinaryOperator<A> mergeOperator) {
+        return this.withSack(new ConstantSupplier<>(initialValue), splitOperator, mergeOperator);
+    }
+
+    /**
+     * Add a sack to be used throughout the life of a spawned {@link Traversal}.
+     * This adds a {@link org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SackStrategy} to the strategies.
+     *
+     * @param initialValue the initial value of the sideEffect
+     * @return a new traversal source with updated strategies
+     */
+    public default <A> TraversalSource withSack(final A initialValue) {
+        return this.withSack(initialValue, null, null);
+    }
+
+    /**
+     * Add a sack to be used throughout the life of a spawned {@link Traversal}.
+     * This adds a {@link org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SackStrategy} to the strategies.
+     *
+     * @param initialValue a supplier that produces the initial value of the sideEffect
+     * @return a new traversal source with updated strategies
+     */
+    public default <A> TraversalSource withSack(final Supplier<A> initialValue) {
+        return this.withSack(initialValue, (UnaryOperator<A>) null, null);
+    }
+
+    /**
+     * Add a sack to be used throughout the life of a spawned {@link Traversal}.
+     * This adds a {@link org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SackStrategy} to the strategies.
+     *
+     * @param initialValue  a supplier that produces the initial value of the sideEffect
+     * @param splitOperator the sack split operator
+     * @return a new traversal source with updated strategies
+     */
+    public default <A> TraversalSource withSack(final Supplier<A> initialValue, final UnaryOperator<A> splitOperator) {
+        return this.withSack(initialValue, splitOperator, null);
+    }
+
+    /**
+     * Add a sack to be used throughout the life of a spawned {@link Traversal}.
+     * This adds a {@link org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SackStrategy} to the strategies.
+     *
+     * @param initialValue  the initial value of the sideEffect
+     * @param splitOperator the sack split operator
+     * @return a new traversal source with updated strategies
+     */
+    public default <A> TraversalSource withSack(final A initialValue, final UnaryOperator<A> splitOperator) {
+        return this.withSack(initialValue, splitOperator, null);
+    }
+
+    /**
+     * Add a sack to be used throughout the life of a spawned {@link Traversal}.
+     * This adds a {@link org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SackStrategy} to the strategies.
+     *
+     * @param initialValue  a supplier that produces the initial value of the sideEffect
+     * @param mergeOperator the sack merge operator
+     * @return a new traversal source with updated strategies
+     */
+    public default <A> TraversalSource withSack(final Supplier<A> initialValue, final BinaryOperator<A> mergeOperator) {
+        return this.withSack(initialValue, null, mergeOperator);
+    }
+
+    /**
+     * Add a sack to be used throughout the life of a spawned {@link Traversal}.
+     * This adds a {@link org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SackStrategy} to the strategies.
+     *
+     * @param initialValue  the initial value of the sideEffect
+     * @param mergeOperator the sack merge operator
+     * @return a new traversal source with updated strategies
+     */
+    public default <A> TraversalSource withSack(final A initialValue, final BinaryOperator<A> mergeOperator) {
+        return this.withSack(initialValue, null, mergeOperator);
+    }
+
+    /**
      * The clone-method should be used to create immutable traversal sources with each call to a configuration method.
      * The clone-method should clone the internal {@link TraversalStrategies}, mutate the cloned strategies accordingly,
      * and then return the cloned traversal source.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/229474ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSourceFactory.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSourceFactory.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSourceFactory.java
deleted file mode 100644
index f955d88..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSourceFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.tinkerpop.gremlin.process.traversal;
-
-import org.apache.tinkerpop.gremlin.structure.Graph;
-
-import java.io.Serializable;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class TraversalSourceFactory<T extends TraversalSource> implements Serializable {
-
-    private final TraversalStrategies traversalStrategies;
-    private final Class<T> traversalSourceClass;
-
-    public TraversalSourceFactory(final T traversalSource) {
-        this.traversalSourceClass = (Class<T>) traversalSource.getClass();
-        this.traversalStrategies = traversalSource.getStrategies();
-    }
-
-    public T createTraversalSource(final Graph graph) {
-        try {
-            return this.traversalSourceClass.getConstructor(Graph.class, TraversalStrategies.class).newInstance(graph, this.traversalStrategies);
-        } catch (final Exception e) {
-            throw new IllegalStateException(e.getMessage(), e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/229474ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
index 8c8d461..97c3f19 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
@@ -27,6 +27,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.engine.ComputerTraversalEn
 import org.apache.tinkerpop.gremlin.process.traversal.engine.StandardTraversalEngine;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStartStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.RequirementsStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SackStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SideEffectStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.TraversalVertexProgramStrategy;
@@ -37,7 +38,6 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Transaction;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -57,8 +57,6 @@ public class GraphTraversalSource implements TraversalSource {
 
     private final Graph graph;
     private TraversalStrategies strategies;
-    private boolean oneBulk = false;
-    private boolean pathOn = false;
 
     public GraphTraversalSource(final Graph graph, final TraversalStrategies traversalStrategies) {
         this.graph = graph;
@@ -72,10 +70,6 @@ public class GraphTraversalSource implements TraversalSource {
     private <S> GraphTraversal.Admin<S, S> generateTraversal() {
         final GraphTraversal.Admin<S, S> traversal = new DefaultGraphTraversal<>(this.graph);
         traversal.setStrategies(this.strategies);
-        if (this.oneBulk)
-            traversal.addTraverserRequirement(TraverserRequirement.ONE_BULK);
-        if (this.pathOn)
-            traversal.addTraverserRequirement(TraverserRequirement.PATH);
         return traversal;
     }
 
@@ -134,63 +128,73 @@ public class GraphTraversalSource implements TraversalSource {
         return clone;
     }
 
-    public GraphTraversalSource withSideEffect(final String key, final Supplier sideEffect) {
+    @Override
+    public GraphTraversalSource withSideEffect(final String key, final Supplier initialValue) {
         final GraphTraversalSource clone = this.clone();
-        SideEffectStrategy.addSideEffect(clone.strategies, key, sideEffect);
+        SideEffectStrategy.addSideEffect(clone.strategies, key, initialValue);
         return clone;
     }
 
-    public GraphTraversalSource withSideEffect(final String key, final Object sideEffect) {
-        final GraphTraversalSource clone = this.clone();
-        SideEffectStrategy.addSideEffect(clone.strategies, key, sideEffect);
-        return clone;
+    @Override
+    public GraphTraversalSource withSideEffect(final String key, final Object initialValue) {
+        return (GraphTraversalSource) TraversalSource.super.withSideEffect(key, initialValue);
     }
 
+    @Override
     public <A> GraphTraversalSource withSack(final Supplier<A> initialValue, final UnaryOperator<A> splitOperator, final BinaryOperator<A> mergeOperator) {
         final GraphTraversalSource clone = this.clone();
-        clone.strategies.addStrategies(new SackStrategy(initialValue, splitOperator, mergeOperator));
+        clone.strategies.addStrategies(SackStrategy.<A>build().initialValue(initialValue).splitOperator(splitOperator).mergeOperator(mergeOperator).create());
         return clone;
     }
 
+    @Override
     public <A> GraphTraversalSource withSack(final A initialValue, final UnaryOperator<A> splitOperator, final BinaryOperator<A> mergeOperator) {
-        final GraphTraversalSource clone = this.clone();
-        clone.strategies.addStrategies(new SackStrategy(new ConstantSupplier<>(initialValue), splitOperator, mergeOperator));
-        return clone;
+        return (GraphTraversalSource) TraversalSource.super.withSack(initialValue, splitOperator, mergeOperator);
     }
 
+    @Override
     public <A> GraphTraversalSource withSack(final A initialValue) {
-        return this.withSack(initialValue, null, null);
+        return (GraphTraversalSource) TraversalSource.super.withSack(initialValue);
     }
 
+    @Override
     public <A> GraphTraversalSource withSack(final Supplier<A> initialValue) {
-        return this.withSack(initialValue, (UnaryOperator<A>) null, null);
+        return (GraphTraversalSource) TraversalSource.super.withSack(initialValue);
     }
 
+    @Override
     public <A> GraphTraversalSource withSack(final Supplier<A> initialValue, final UnaryOperator<A> splitOperator) {
-        return this.withSack(initialValue, splitOperator, null);
+        return (GraphTraversalSource) TraversalSource.super.withSack(initialValue, splitOperator);
     }
 
+    @Override
     public <A> GraphTraversalSource withSack(final A initialValue, final UnaryOperator<A> splitOperator) {
-        return this.withSack(initialValue, splitOperator, null);
+        return (GraphTraversalSource) TraversalSource.super.withSack(initialValue, splitOperator);
     }
 
+    @Override
     public <A> GraphTraversalSource withSack(final Supplier<A> initialValue, final BinaryOperator<A> mergeOperator) {
-        return this.withSack(initialValue, null, mergeOperator);
+        return (GraphTraversalSource) TraversalSource.super.withSack(initialValue, mergeOperator);
     }
 
+    @Override
     public <A> GraphTraversalSource withSack(final A initialValue, final BinaryOperator<A> mergeOperator) {
-        return this.withSack(initialValue, null, mergeOperator);
+        return (GraphTraversalSource) TraversalSource.super.withSack(initialValue, mergeOperator);
     }
 
     public GraphTraversalSource withBulk(final boolean useBulk) {
-        final GraphTraversalSource clone = this.clone();
-        clone.oneBulk = !useBulk;
-        return clone;
+        if (!useBulk) {
+            final GraphTraversalSource clone = this.clone();
+            RequirementsStrategy.addRequirements(clone.strategies, TraverserRequirement.ONE_BULK);
+            return clone;
+        } else {
+            return this;
+        }
     }
 
     public GraphTraversalSource withPath() {
         final GraphTraversalSource clone = this.clone();
-        clone.pathOn = true;
+        RequirementsStrategy.addRequirements(clone.strategies, TraverserRequirement.PATH);
         return clone;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/229474ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/RequirementsStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/RequirementsStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/RequirementsStep.java
new file mode 100644
index 0000000..4740f78
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/RequirementsStep.java
@@ -0,0 +1,55 @@
+/*
+ * 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 org.apache.tinkerpop.gremlin.process.traversal.step.util;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+
+import java.util.HashSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class RequirementsStep<S> extends AbstractStep<S, S> {
+
+    private final Set<TraverserRequirement> requirements;
+
+    public RequirementsStep(final Traversal.Admin traversal, final Set<TraverserRequirement> requirements) {
+        super(traversal);
+        this.requirements = new HashSet<>(requirements);
+    }
+
+    public void addRequirement(final TraverserRequirement requirement) {
+        this.requirements.add(requirement);
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return this.requirements;
+    }
+
+    @Override
+    protected Traverser<S> processNextStart() throws NoSuchElementException {
+        return this.starts.next();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/229474ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/RequirementsStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/RequirementsStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/RequirementsStrategy.java
new file mode 100644
index 0000000..bfd4853
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/RequirementsStrategy.java
@@ -0,0 +1,59 @@
+/*
+ * 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 org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.RequirementsStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class RequirementsStrategy extends AbstractTraversalStrategy<TraversalStrategy.DecorationStrategy> implements TraversalStrategy.DecorationStrategy {
+
+    private final Set<TraverserRequirement> requirements = new HashSet<>();
+
+    private RequirementsStrategy() {
+    }
+
+    @Override
+    public void apply(final Traversal.Admin<?, ?> traversal) {
+        if (traversal.getParent() instanceof EmptyStep && !this.requirements.isEmpty())
+            traversal.addStep(new RequirementsStep<>(traversal, this.requirements));
+    }
+
+    public static void addRequirements(final TraversalStrategies traversalStrategies, final TraverserRequirement... requirements) {
+        RequirementsStrategy strategy = (RequirementsStrategy) traversalStrategies.toList().stream().filter(s -> s instanceof RequirementsStrategy).findAny().orElse(null);
+        if (null == strategy) {
+            strategy = new RequirementsStrategy();
+            traversalStrategies.addStrategies(strategy);
+        }
+        for (final TraverserRequirement requirement : requirements) {
+            strategy.requirements.add(requirement);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/229474ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SackStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SackStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SackStrategy.java
index 16719f9..0598d17 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SackStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SackStrategy.java
@@ -37,8 +37,9 @@ public final class SackStrategy extends AbstractTraversalStrategy<TraversalStrat
     private final UnaryOperator splitOperator;
     private final BinaryOperator mergeOperator;
 
-
-    public SackStrategy(final Supplier initialValue, final UnaryOperator splitOperator, final BinaryOperator mergeOperator) {
+    private SackStrategy(final Supplier initialValue, final UnaryOperator splitOperator, final BinaryOperator mergeOperator) {
+        if (null == initialValue)
+            throw new IllegalArgumentException("The initial value of a sack can not be null");
         this.initialValue = initialValue;
         this.splitOperator = splitOperator;
         this.mergeOperator = mergeOperator;
@@ -49,4 +50,37 @@ public final class SackStrategy extends AbstractTraversalStrategy<TraversalStrat
         if (traversal.getParent() instanceof EmptyStep)
             traversal.getSideEffects().setSack(this.initialValue, this.splitOperator, this.mergeOperator);
     }
+
+    public static <A> Builder<A> build() {
+        return new Builder<>();
+    }
+
+    public final static class Builder<A> {
+
+        private Supplier<A> initialValue;
+        private UnaryOperator<A> splitOperator = null;
+        private BinaryOperator<A> mergeOperator = null;
+
+        private Builder() {
+        }
+
+        public Builder initialValue(final Supplier<A> initialValue) {
+            this.initialValue = initialValue;
+            return this;
+        }
+
+        public Builder splitOperator(final UnaryOperator<A> splitOperator) {
+            this.splitOperator = splitOperator;
+            return this;
+        }
+
+        public Builder mergeOperator(final BinaryOperator<A> mergeOperator) {
+            this.mergeOperator = mergeOperator;
+            return this;
+        }
+
+        public SackStrategy create() {
+            return new SackStrategy(this.initialValue, this.splitOperator, this.mergeOperator);
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/229474ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalScriptFunction.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalScriptFunction.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalScriptFunction.java
index 7ab980d..e096934 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalScriptFunction.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalScriptFunction.java
@@ -20,7 +20,6 @@ package org.apache.tinkerpop.gremlin.process.traversal.util;
 
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalSourceFactory;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/229474ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalSourceFactory.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalSourceFactory.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalSourceFactory.java
new file mode 100644
index 0000000..5c11c7e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalSourceFactory.java
@@ -0,0 +1,52 @@
+/*
+ * 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 org.apache.tinkerpop.gremlin.process.traversal.util;
+
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+
+import java.io.Serializable;
+
+/**
+ * {@link TraversalSource} is not {@link Serializable}.
+ * {@code TraversalSourceFactory} can be used to create a serializable representation of a traversal source.
+ * This is is primarily an internal utility class for use and should not be used by standard users.
+ *
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class TraversalSourceFactory<T extends TraversalSource> implements Serializable {
+
+    private final TraversalStrategies traversalStrategies;
+    private final Class<T> traversalSourceClass;
+
+    public TraversalSourceFactory(final T traversalSource) {
+        this.traversalSourceClass = (Class<T>) traversalSource.getClass();
+        this.traversalStrategies = traversalSource.getStrategies();
+    }
+
+    public T createTraversalSource(final Graph graph) {
+        try {
+            return this.traversalSourceClass.getConstructor(Graph.class, TraversalStrategies.class).newInstance(graph, this.traversalStrategies);
+        } catch (final Exception e) {
+            throw new IllegalStateException(e.getMessage(), e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/229474ab/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/loaders/StepLoader.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/loaders/StepLoader.groovy b/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/loaders/StepLoader.groovy
index 7eccde4..ccf1a2c 100644
--- a/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/loaders/StepLoader.groovy
+++ b/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/loaders/StepLoader.groovy
@@ -18,9 +18,8 @@
  */
 package org.apache.tinkerpop.gremlin.groovy.loaders
 
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
-import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource
-import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier
 
 import java.util.function.BinaryOperator
 import java.util.function.Function
@@ -38,21 +37,21 @@ class StepLoader {
             return ((GraphTraversal) delegate).by(1 == closure.getMaximumNumberOfParameters() ? closure as Function : closure as Comparator);
         }
 
-        GraphTraversalSource.metaClass.withSideEffect = { final String key, final Object object ->
-            return ((GraphTraversalSource) delegate).withSideEffect(key, object instanceof Closure ? ((Closure) object) as Supplier : new ConstantSupplier<>(object));
+        TraversalSource.metaClass.withSideEffect = { final String key, final Closure object ->
+            return ((TraversalSource) delegate).withSideEffect(key, object as Supplier);
         }
 
-        GraphTraversalSource.metaClass.withSack = { final Closure closure ->
-            return ((GraphTraversalSource) delegate).withSack(closure as Supplier);
+        TraversalSource.metaClass.withSack = { final Closure closure ->
+            return ((TraversalSource) delegate).withSack(closure as Supplier);
         }
 
-        GraphTraversalSource.metaClass.withSack = { final Closure closure, final Closure splitOrMergeOperator ->
-            return ((GraphTraversalSource) delegate).withSack(closure as Supplier, splitOrMergeOperator.getMaximumNumberOfParameters() == 1 ? splitOrMergeOperator as UnaryOperator : splitOrMergeOperator as BinaryOperator);
+        TraversalSource.metaClass.withSack = { final Closure closure, final Closure splitOrMergeOperator ->
+            return ((TraversalSource) delegate).withSack(closure as Supplier, splitOrMergeOperator.getMaximumNumberOfParameters() == 1 ? splitOrMergeOperator as UnaryOperator : splitOrMergeOperator as BinaryOperator);
         }
 
-        GraphTraversalSource.metaClass.withSack = {
+        TraversalSource.metaClass.withSack = {
             final Closure closure, final Closure splitOperator, final Closure mergeOperator ->
-                return ((GraphTraversalSource) delegate).withSack(closure as Supplier, splitOperator as UnaryOperator, mergeOperator as BinaryOperator);
+                return ((TraversalSource) delegate).withSack(closure as Supplier, splitOperator as UnaryOperator, mergeOperator as BinaryOperator);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/229474ab/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/loaders/SugarLoader.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/loaders/SugarLoader.groovy b/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/loaders/SugarLoader.groovy
index ac0e607..bfc877e 100644
--- a/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/loaders/SugarLoader.groovy
+++ b/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/loaders/SugarLoader.groovy
@@ -32,8 +32,6 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory
 class SugarLoader {
 
     private static final String NAME = "name";
-    //private static final String FROM = "from";
-    //private static final String SELECT = "select";
 
     public static void load() {
 
@@ -46,11 +44,9 @@ class SugarLoader {
         Traverser.metaClass.methodMissing = { final String name, final def args ->
             ((Traverser) delegate).get()."$name"(*args);
         }
+
         // g.V.age
         GraphTraversal.metaClass.methodMissing = { final String name, final def args ->
-            //if (name.toLowerCase().equals(FROM))
-            //    return ((GraphTraversal.Admin) args[0]).addStep(((GraphTraversal.Admin) delegate).getSteps()[0]);
-            //else
             return ((GraphTraversal) delegate).values(name);
         }
 
@@ -58,10 +54,6 @@ class SugarLoader {
             GraphTraversalSourceCategory.get((GraphTraversalSource) delegate, key);
         }
 
-        /*GraphTraversalSource.GraphTraversalSourceStub.metaClass.getProperty = { final String key ->
-            GraphTraversalSourceStubCategory.get((GraphTraversalSource.GraphTraversalSourceStub) delegate, key);
-        }*/
-
         // __.age and __.out
         __.metaClass.static.propertyMissing = { final String name ->
             return null != __.metaClass.getMetaMethod(name) ? __."$name"() : __.values(name);
@@ -78,15 +70,8 @@ class SugarLoader {
                 return __."$name";
         }*/
 
-        // select x,y from ...
-        /*Object.metaClass.methodMissing = { final String name, final def args ->
-            if (name.toLowerCase().equals(SELECT)) return __.select(*args)
-            throw new MissingMethodException(name, delegate.getClass(), args);
-        }*/
-
         Traverser.metaClass.mixin(TraverserCategory.class);
         GraphTraversalSource.metaClass.mixin(GraphTraversalSourceCategory.class);
-        //GraphTraversalSource.GraphTraversalSourceStub.metaClass.mixin(GraphTraversalSourceStubCategory.class);
         GraphTraversal.metaClass.mixin(GraphTraversalCategory.class);
         Vertex.metaClass.mixin(VertexCategory.class);
         Edge.metaClass.mixin(ElementCategory.class);
@@ -167,26 +152,6 @@ class SugarLoader {
         }
     }
 
-    /*public static class GraphTraversalSourceStubCategory {
-
-        private static final String V = "V";
-        private static final String E = "E";
-
-        public static final get(
-                final GraphTraversalSource.GraphTraversalSourceStub graphTraversalSourceStub, final String key) {
-            if (key.equals(V))
-                return graphTraversalSourceStub.V();
-            else if (key.equals(E))
-                return graphTraversalSourceStub.E();
-            else
-                throw new UnsupportedOperationException("The provided key does not reference a known method: " + key);
-        }
-
-        /*public String toString() {
-            return StringFactory.traversalSourceString(this.metaClass.owner);
-        }
-    }*/
-
     public static class GraphTraversalCategory {
 
         public static final get(final GraphTraversal graphTraversal, final String key) {