/**
   * Moves the operators from this process to another process, keeping all connections intact. TODO:
   * Test more rigorously. Do we register/unregister everything correctly?
   *
   * @return the number of ports the connections of which could not be restored
   */
  public int stealOperatorsFrom(ExecutionUnit otherUnit) {
    int failedReconnects = 0;

    // remember source and sink connections so we can reconnect them later.
    Map<String, InputPort> sourceMap = new HashMap<String, InputPort>();
    Map<String, OutputPort> sinkMap = new HashMap<String, OutputPort>();
    for (OutputPort source : otherUnit.getInnerSources().getAllPorts()) {
      if (source.isConnected()) {
        sourceMap.put(source.getName(), source.getDestination());
      }
    }
    otherUnit.getInnerSources().disconnectAll();
    for (InputPort sink : otherUnit.getInnerSinks().getAllPorts()) {
      if (sink.isConnected()) {
        sinkMap.put(sink.getName(), sink.getSource());
      }
    }
    otherUnit.getInnerSinks().disconnectAll();

    // Move operators
    Iterator<Operator> i = otherUnit.operators.iterator();
    while (i.hasNext()) {
      Operator operator = i.next();
      i.remove();
      otherUnit.unregister(operator);
      Process otherProcess = operator.getProcess();
      if (otherProcess != null) {
        operator.unregisterOperator(otherProcess);
      }
      this.operators.add(operator);
      operator.setEnclosingProcess(null);
      // operator.unregisterOperator(operator.getProcess());
      registerOperator(operator, true);
      // operator.registerOperator(this.getEnclosingOperator().getProcess());
    }

    // Rewire sources and sinks
    for (Map.Entry<String, InputPort> entry : sourceMap.entrySet()) {
      OutputPort mySource = getInnerSources().getPortByName(entry.getKey());
      if (mySource != null) {
        mySource.connectTo(entry.getValue());
      } else {
        failedReconnects++;
      }
    }
    getInnerSources().unlockPortExtenders();

    for (Map.Entry<String, OutputPort> entry : sinkMap.entrySet()) {
      InputPort mySink = getInnerSinks().getPortByName(entry.getKey());
      if (mySink != null) {
        entry.getValue().connectTo(mySink);
      } else {
        failedReconnects++;
      }
    }
    getInnerSinks().unlockPortExtenders();

    fireUpdate(this);
    return failedReconnects;
  }
  /**
   * 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;
  }