docs: @Override
      public QueryResults execute( final QueryContext queryContext,
                                   final QueryCommand query ) throws QueryCancelledException, RepositoryException {
          CheckArg.isNotNull(queryContext, "queryContext");
          CheckArg.isNotNull(query, "query");
          final ScanQueryContext context = (ScanQueryContext)queryContext;
  
          checkCancelled(context);
  
          // Validate that all of the referenced variables have been provided ...
          Visitors.visitAll(query, new Visitors.AbstractVisitor() {
              @Override
              public void visit( BindVariableName obj ) {
                  if (!context.getVariables().keySet().contains(obj.getBindVariableName())) {
                      context.getProblems().addError(GraphI18n.missingVariableValue, obj.getBindVariableName());
                  }
              }
          });
  
          boolean trace = LOGGER.isTraceEnabled();
          if (trace) {
              LOGGER.trace("Beginning to process query {3} against workspace(s) {0} in '{1}' repository: {2}",
                           context.getWorkspaceNames(), repositoryName, query, context.id());
          }
  
          // Create the canonical plan ...
          long start = System.nanoTime();
          PlanNode plan = planner.createPlan(context, query);
          long duration = Math.abs(System.nanoTime() - start);
          Statistics stats = new Statistics(duration);
          final String workspaceName = context.getWorkspaceNames().iterator().next();
  
          if (trace) {
              LOGGER.trace("Computed canonical query plan for query {0}: {1}", context.id(), plan);
          }
  
          checkCancelled(context);
          Columns resultColumns = null;
          if (!context.getProblems().hasErrors()) {
              // Optimize the plan ...
              start = System.nanoTime();
              PlanNode optimizedPlan = optimizer.optimize(context, plan);
              duration = Math.abs(System.nanoTime() - start);
              stats = stats.withOptimizationTime(duration);
  
              if (trace) {
                  LOGGER.trace("Computed optimized query plan for query {0}:\n{1}", context.id(), optimizedPlan);
              }
  
              // Find the query result columns ...
              start = System.nanoTime();
  
              // Determine the Columns object for specific nodes in the plan, and store them in the context ...
              optimizedPlan.apply(Traversal.POST_ORDER, new PlanNode.Operation() {
  
                  @Override
                  public void apply( PlanNode node ) {
                      Columns columns = null;
                      switch (node.getType()) {
                          case PROJECT:
                          case SOURCE:
                              columns = determineProjectedColumns(node, context);
                              assert columns != null;
                              break;
                          case JOIN:
                              Columns leftColumns = context.columnsFor(node.getFirstChild());
                              Columns rightColumns = context.columnsFor(node.getLastChild());
                              columns = leftColumns.with(rightColumns);
                              assert columns != null;
                              break;
                          case DEPENDENT_QUERY:
                              columns = context.columnsFor(node.getLastChild());
                              assert columns != null;
                              break;
                          case SET_OPERATION:
                              leftColumns = context.columnsFor(node.getFirstChild());
                              rightColumns = context.columnsFor(node.getLastChild());
                              if (checkUnionCompatible(leftColumns, rightColumns, context, query)) {
                                  columns = leftColumns;
                                  assert columns != null;
                              }
                              break;
                          case INDEX:
                              // do nothing with indexes ...
                              break;
                          default:
                              assert node.getChildCount() == 1;
                              columns = context.columnsFor(node.getFirstChild());
                              assert columns != null;
                              break;
                      }
                      if (columns != null) {
                          context.addColumnsFor(node, columns);
                      }
                  }
              });
              Problems problems = context.getProblems();
              if (problems.hasErrors()) {
                  throw new RepositoryException(JcrI18n.problemsWithQuery.text(query, problems.toString()));
              } else if (LOGGER.isDebugEnabled() && problems.hasWarnings()) {
                  LOGGER.debug("There are several warnings with this query: {0}\n{1}", query, problems.toString());
              }
  
              resultColumns = context.columnsFor(optimizedPlan);
              assert resultColumns != null;
              duration = Math.abs(System.nanoTime() - start);
              stats = stats.withResultsFormulationTime(duration);
  
              if (trace) {
                  LOGGER.trace("Computed output columns for query {0}: {1}", context.id(), resultColumns);
              }
  
              if (!context.getProblems().hasErrors()) {
                  checkCancelled(context);
                  // Execute the plan ...
                  try {
                      start = System.nanoTime();
                      if (trace) {
                          LOGGER.trace("Start executing query {0}", context.id());
                      }
                      QueryResults results = executeOptimizedQuery(context, query, stats, optimizedPlan);
                      if (trace) {
                          LOGGER.trace("Stopped executing query {0}: {1}", context.id(), stats);
                      }
                      return results;
                  } finally {
                      duration = Math.abs(System.nanoTime() - start);
                      stats = stats.withExecutionTime(duration);
                  }
              }
          }
          // Check whether the query was cancelled during execution ...
          checkCancelled(context);
  
          if (resultColumns == null) resultColumns = ResultColumns.EMPTY;
  
          // There were problems somewhere ...
          int width = resultColumns.getColumns().size();
          CachedNodeSupplier cachedNodes = context.getNodeCache(workspaceName);
          return new Results(resultColumns, stats, NodeSequence.emptySequence(width), cachedNodes, context.getProblems(), null);
      }