/**
   * 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;
  }
 /**
  * Adds the operator to this execution unit. The operator at this index and all subsequent
  * operators are shifted to the right. The operator is registered automatically.
  */
 public void addOperator(Operator operator, int index) {
   if (operator == null) {
     throw new NullPointerException("operator cannot be null!");
   }
   if (operator instanceof ProcessRootOperator) {
     throw new IllegalArgumentException(
         "'Process' operator cannot be added. It must always be the top-level operator!");
   }
   operators.add(index, operator);
   registerOperator(operator, true);
 }
 /**
  * Adds the operator to this execution unit.
  *
  * @param registerWithProcess Typically true. If false, the operator will not be registered with
  *     its parent process.
  * @return the new index of the operator.
  */
 public int addOperator(Operator operator, boolean registerWithProcess) {
   if (operator == null) {
     throw new NullPointerException("operator cannot be null!");
   }
   if (operator instanceof ProcessRootOperator) {
     throw new IllegalArgumentException(
         "'Process' operator cannot be added. It must always be the top-level operator!");
   }
   operators.add(operator);
   registerOperator(operator, registerWithProcess);
   return operators.size() - 1;
 }