code: public static boolean isExtractable(GroovyExpression expr) {
  
          HasForbiddenType hasForbiddenTypePredicate = new HasForbiddenType(FACTORY);
  
          //alias could conflict with alias in parent traversal
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.SIDE_EFFECT);
  
          //inlining out(), in() steps will change the result of calls after the and/or()
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.FLAT_MAP_TO_ELEMENTS);
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.FLAT_MAP_TO_VALUES);
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.BARRIER);
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.MAP_TO_ELEMENT);
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.MAP_TO_VALUE);
  
          //caller expects to be able to continue the traversal.  We can't end it
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.END);
  
  
          //we can't inline child traversals
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.SOURCE);
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.START);
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.SIDE_EFFECT);
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.NONE);
          hasForbiddenTypePredicate.addForbiddenType(TraversalStepType.BRANCH);
  
          ExpressionFinder forbiddenExpressionFinder = new ExpressionFinder(hasForbiddenTypePredicate);
          GremlinQueryOptimizer.visitCallHierarchy(expr, forbiddenExpressionFinder);
          return ! forbiddenExpressionFinder.isExpressionFound();
      }
docs: Determines whether the given expression can safely
  be pulled out of an and/or expression.
  
  @param expr an argument to an and or or function
  @return