/**
   * Clones operators contained in <code>original</code>, adds them to this execution unit and wires
   * them as they were originally.
   *
   * @param forParallelExecution Indicates whether this clone is supposed to be executed in
   *     parallel. If yes, the clone will not be registered with the parent process and will share
   *     its {@link Operator#applyCount} with the original.
   */
  public void cloneExecutionUnitFrom(ExecutionUnit original, boolean forParallelExecution) {
    // Clone operators
    Map<String, Operator> clonedOperatorsByName = new HashMap<String, Operator>();
    for (Operator originalChild : original.operators) {
      Operator clonedOperator =
          originalChild.cloneOperator(originalChild.getName(), forParallelExecution);
      addOperator(clonedOperator, !forParallelExecution);
      clonedOperatorsByName.put(originalChild.getName(), clonedOperator);
    }

    // Restore connections
    cloneConnections(original.getInnerSources(), original, clonedOperatorsByName);
    for (Operator op : original.operators) {
      cloneConnections(op.getOutputPorts(), original, clonedOperatorsByName);
    }

    // Unlock
    original.getInnerSources().unlockPortExtenders();
    original.getInnerSinks().unlockPortExtenders();
    for (Operator op : this.operators) {
      op.getInputPorts().unlockPortExtenders();
      op.getOutputPorts().unlockPortExtenders();
    }

    // Other:
    this.expanded = original.expanded;
  }