docs: public void perform(GraphRewrite event, EvaluationContext context)
      {
          Variables variables = Variables.instance(event);
          Iterable<? extends WindupVertexFrame> frames = getSelectionManager().getFrames(event, context);
  
          boolean hasCommitOperation = OperationUtil.hasCommitOperation(operationPerform) || OperationUtil.hasCommitOperation(operationOtherwise);
          boolean hasIterationOperation = OperationUtil.hasIterationProgress(operationPerform)
                      || OperationUtil.hasIterationProgress(operationOtherwise);
          DefaultOperationBuilder commit = new NoOp();
          DefaultOperationBuilder iterationProgressOperation = new NoOp();
  
          if (!hasCommitOperation || !hasIterationOperation)
          {
              int frameCount = Iterables.size(frames);
              if (frameCount > 100)
              {
                  if (!hasCommitOperation)
                      commit = Commit.every(1000);
  
                  if (!hasIterationOperation)
                  {
                      // Use 500 here as 100 might be noisy.
                      iterationProgressOperation = IterationProgress.monitoring("Rule Progress", 500);
                  }
              }
          }
          Operation commitAndProgress = commit.and(iterationProgressOperation);
  
          event.getRewriteContext().put(DEFAULT_VARIABLE_LIST_STRING, frames); // set the current frames
          try
          {
              for (WindupVertexFrame frame : frames)
              try
              {
                  variables.push();
                  getPayloadManager().setCurrentPayload(variables, frame);
                  boolean conditionResult = true;
                  if (condition != null)
                  {
                      final String payloadVariableName = getPayloadVariableName(event, context);
                      passInputVariableNameToConditionTree(condition, payloadVariableName);
                      conditionResult = condition.evaluate(event, context);
                      /*
                       * Add special clear layer for perform, because condition used one and could have added new variables. The condition result put into
                       * variables is ignored.
                       */
                      variables.push();
                      getPayloadManager().setCurrentPayload(variables, frame);
                  }
                  if (conditionResult)
                  {
                      if (operationPerform != null)
                      {
                          operationPerform.perform(event, context);
                      }
                  }
                  else if (condition != null)
                  {
                      if (operationOtherwise != null)
                      {
                          operationOtherwise.perform(event, context);
                      }
                  }
                  commitAndProgress.perform(event, context);
  
                  getPayloadManager().removeCurrentPayload(variables);
                  // remove the perform layer
                  variables.pop();
                  if (condition != null)
                  {
                      // remove the condition layer
                      variables.pop();
                  }
              }
              catch (WindupStopException ex)
              {
                  throw new WindupStopException(Util.WINDUP_BRAND_NAME_ACRONYM+" stop requested in " + this.toString(), ex);
              }
              catch (Exception e)
              {
                  throw new WindupException("Failed when iterating " + frame.toPrettyString() + ", due to: " + e.getMessage(), e);
              }
          }
          finally
          {
              event.getRewriteContext().put(DEFAULT_VARIABLE_LIST_STRING, null);
          }
      }