/**
   * @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);
    }
  }
 /**
  * Connects the ports automatically in a first-fit approach. Operators are connected in their
  * ordering within the {@link #operators} list. Every input of every operator is connected to the
  * first compatible output of an operator "left" of this operator. This corresponds to the way,
  * IOObjects were consumed in the pre-5.0 version. Disabled operators are skipped. <br>
  *
  * @param level If level is {@link CompatibilityLevel#VERSION_5}, an input is considered
  *     compatible only if it satisfies all meta data constraints. For {@link
  *     CompatibilityLevel#PRE_VERSION_5} we only consider the classes.
  * @param keepConnections if true, don't unwire old connections before rewiring.
  */
 public void autoWire(CompatibilityLevel level, boolean keepConnections, boolean recursive)
     throws PortException {
   if (!keepConnections) {
     unwire(recursive);
   }
   // store all outputs. Scan them to find matching inputs.
   LinkedList<OutputPort> readyOutputs = new LinkedList<OutputPort>();
   addReadyOutputs(readyOutputs, getInnerSources());
   List<Operator> enabled = new LinkedList<Operator>();
   for (Operator op : getOperators()) {
     if (op.isEnabled()) {
       enabled.add(op);
     }
   }
   autoWire(level, enabled, readyOutputs, recursive, true);
 }