/**
   * @param wireNew If true, OutputPorts of operators will be added to readyOutputs once they are
   *     wired.
   */
  private void autoWire(
      CompatibilityLevel level,
      List<Operator> operators,
      LinkedList<OutputPort> readyOutputs,
      boolean recursive,
      boolean wireNew)
      throws PortException {
    transformMDNeighbourhood();

    for (Operator op : operators) {
      try {
        readyOutputs = op.preAutoWire(readyOutputs);
      } catch (OperatorException e) {
        getEnclosingOperator().getLogger().log(Level.WARNING, "During auto-wiring: " + e, e);
      }
      autoWire(level, op.getInputPorts(), readyOutputs);
      transformMDNeighbourhood();
      if (recursive) {
        if (op instanceof OperatorChain) {
          for (ExecutionUnit subprocess : ((OperatorChain) op).getSubprocesses()) {
            // we have already removed all connections, so keepConnections=true in recursive call
            subprocess.autoWire(level, true, recursive);
          }
        }
      }
      if (wireNew) {
        addReadyOutputs(readyOutputs, op.getOutputPorts());
      }
    }
    autoWire(level, getInnerSinks(), readyOutputs);
    transformMDNeighbourhood();
  }
  /**
   * Automatically wires inputs and outputs of a single operator in this execution unit.
   *
   * @param inputs Wire inputs?
   * @param outputs Wire outputs?
   */
  public void autoWireSingle(
      Operator operator, CompatibilityLevel level, boolean inputs, boolean outputs) {
    // auto wire inputs
    if (inputs) {
      transformMDNeighbourhood();
      // store all outputs. Scan them to find matching inputs.
      LinkedList<OutputPort> readyOutputs = new LinkedList<OutputPort>();
      // add the ports, oldest first. Simulate pre-5.0-like stack by taking
      // the last out of this list when consuming input.
      addReadyOutputs(readyOutputs, getInnerSources());
      boolean found = false;
      for (Operator other : operators) {
        if (other == operator) {
          found = true;
          break;
        } else {
          addReadyOutputs(readyOutputs, other.getOutputPorts());
        }
      }
      if (!found) {
        throw new IllegalArgumentException(
            "Operator "
                + operator.getName()
                + " does not belong to this subprocess "
                + getName()
                + ".");
      }
      getEnclosingOperator()
          .getLogger()
          .fine(
              "Wiring: "
                  + operator
                  + "."
                  + operator.getInputPorts().getAllPorts()
                  + " to "
                  + readyOutputs);
      autoWire(level, operator.getInputPorts(), readyOutputs);
    }

    // auto wire outputs
    if (outputs) {
      LinkedList<OutputPort> readyOutputs = new LinkedList<OutputPort>();
      addReadyOutputs(readyOutputs, operator.getOutputPorts());
      List<Operator> successors = new LinkedList<Operator>();
      boolean foundMe = false;
      for (Operator other : getOperators()) {
        if (foundMe) {
          successors.add(other);
        } else if (other == operator) {
          foundMe = true;
        }
      }
      autoWire(level, successors, readyOutputs, false, false);
    }
  }