class HugeVertexStepStrategy
        extends AbstractTraversalStrategy<ProviderOptimizationStrategy>
        implements ProviderOptimizationStrategy {

    private static final long serialVersionUID = 491355700217483162L;

    private static final HugeVertexStepStrategy INSTANCE;

    static {
        INSTANCE = new HugeVertexStepStrategy();
    }

    private HugeVertexStepStrategy() {
        // pass
    }

    @Override
    @SuppressWarnings({"rawtypes", "unchecked"})
    public void apply(final Traversal.Admin<?, ?> traversal) {
        TraversalUtil.convAllHasSteps(traversal);

        List<VertexStep> steps = TraversalHelper.getStepsOfClass(
                VertexStep.class, traversal);

        boolean batchOptimize = false;
        if (!steps.isEmpty()) {
            boolean withPath = HugeVertexStepStrategy.containsPath(traversal);
            boolean withTree = HugeVertexStepStrategy.containsTree(traversal);
            /*
             * The graph of traversal may be null when `__` step is followed
             * by `count().is(0)` step, like the following gremlin:
             * `g.V(id).repeat(in()).until(or(inE().count().is(0), loops().is(2)))`
             * TODO: remove this `graph!=null` check after fixed the bug #1699
             */
            boolean supportIn = false;
            HugeGraph graph = TraversalUtil.tryGetGraph(steps.get(0));
            if (graph != null) {
                supportIn = graph.backendStoreFeatures()
                                 .supportsQueryWithInCondition();
            }
            batchOptimize = !withTree && !withPath && supportIn;
        }

        for (VertexStep originStep : steps) {
            HugeVertexStep<?> newStep = batchOptimize ?
                                        new HugeVertexStepByBatch<>(originStep) :
                                        new HugeVertexStep<>(originStep);
            TraversalHelper.replaceStep(originStep, newStep, traversal);

            TraversalUtil.extractHasContainer(newStep, traversal);

            // TODO: support order-by optimize
            // TraversalUtil.extractOrder(newStep, traversal);

            TraversalUtil.extractRange(newStep, traversal, true);

            TraversalUtil.extractCount(newStep, traversal);
        }
    }

    /**
     * Does a Traversal contain any Path step
     *
     * @param traversal
     * @return the traversal or its parents contain at least one Path step
     */
    protected static boolean containsPath(Traversal.Admin<?, ?> traversal) {
        boolean hasPath = !TraversalHelper.getStepsOfClass(
                PathStep.class, traversal).isEmpty();
        if (hasPath) {
            return true;
        } else if (traversal instanceof EmptyTraversal) {
            return false;
        }

        TraversalParent parent = traversal.getParent();
        return containsPath(parent.asStep().getTraversal());
    }

    /**
     * Does a Traversal contain any Tree step
     *
     * @param traversal
     * @return the traversal or its parents contain at least one Tree step
     */
    protected static boolean containsTree(Traversal.Admin<?, ?> traversal) {<FILL_FUNCTION_BODY>}

    public static HugeVertexStepStrategy instance() {
        return INSTANCE;
    }
}

        boolean hasTree = !TraversalHelper.getStepsOfClass(
                TreeStep.class, traversal).isEmpty();
        if (hasTree) {
            return true;
        } else if (traversal instanceof EmptyTraversal) {
            return false;
        }

        TraversalParent parent = traversal.getParent();
        return containsTree(parent.asStep().getTraversal());
    
<no_super_class>