/**
   * Displays an error bubble that alerts the user that an input port of an operator expected input
   * but did not receive any. The bubble is located at the port and the process view will change to
   * said port. This method is used after the error occurred during process execution.
   *
   * @param port the port for which to display the error
   * @return the {@link PortInfoBubble} instance, never {@code null}
   */
  public static PortInfoBubble displayInputPortNoDataInformation(final Port port) {
    if (port == null) {
      throw new IllegalArgumentException("port must not be null!");
    }

    String key;
    if (port.isConnected()) {
      key = "process_mandatory_input_port_no_data";
    } else {
      // PortOwner is an interface only implemented from anonymous inner classes
      // so check enclosing class and differentiate operator input ports and subprocess
      // (result) input ports
      if (ExecutionUnit.class.isAssignableFrom(
          port.getPorts().getOwner().getClass().getEnclosingClass())) {
        key = "process_mandatory_input_port_no_data_unconnected_inner";
      } else {
        key = "process_mandatory_input_port_no_data_unconnected";
      }
    }
    String opName = "";
    if (port instanceof InputPort) {
      InputPort inPort = (InputPort) port;
      OutputPort source = inPort.getSource();
      if (source != null) {
        // not the user entered name because that could be god knows how long
        opName = source.getPorts().getOwner().getOperator().getOperatorDescription().getName();
      }
    }
    return displayMissingInputPortInformation(port, !port.isConnected(), true, key, opName);
  }
 @SuppressWarnings("deprecation")
 private void autoWire(
     CompatibilityLevel level, InputPorts inputPorts, LinkedList<OutputPort> readyOutputs)
     throws PortException {
   boolean success = false;
   do {
     Set<InputPort> complete = new HashSet<InputPort>();
     for (InputPort in : inputPorts.getAllPorts()) {
       success = false;
       if (!in.isConnected()
           && !complete.contains(in)
           && in.getPorts().getOwner().getOperator().shouldAutoConnect(in)) {
         Iterator<OutputPort> outIterator;
         // TODO: Simon: Does the same in both cases. Check again.
         if (in.simulatesStack()) {
           outIterator = readyOutputs.descendingIterator();
         } else {
           outIterator = readyOutputs.descendingIterator();
         }
         while (outIterator.hasNext()) {
           OutputPort outCandidate = outIterator.next();
           // TODO: Remove shouldAutoConnect() in later versions
           Operator owner = outCandidate.getPorts().getOwner().getOperator();
           if (owner.shouldAutoConnect(outCandidate)) {
             if (outCandidate.getMetaData() != null) {
               if (in.isInputCompatible(outCandidate.getMetaData(), level)) {
                 readyOutputs.remove(outCandidate);
                 outCandidate.connectTo(in);
                 // we cannot continue with the remaining input ports
                 // since connecting may have triggered the creation of new input ports
                 // which would result in undefined behavior and a ConcurrentModificationException
                 success = true;
                 break;
               }
             }
           }
         }
         // no port found.
         complete.add(in);
         if (success) {
           break;
         }
       }
     }
   } while (success);
 }
  private void cloneConnections(
      OutputPorts originalPorts,
      ExecutionUnit originalExecutionUnit,
      Map<String, Operator> clonedOperatorsByName) {
    for (OutputPort originalSource : originalPorts.getAllPorts()) {
      if (originalSource.isConnected()) {

        OutputPort mySource;
        if (originalPorts.getOwner().getOperator()
            == originalExecutionUnit.getEnclosingOperator()) {
          // this is an inner source
          mySource = getInnerSources().getPortByName(originalSource.getName());
          if (mySource == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding source for "
                    + originalSource
                    + " not found (no such inner source).");
          }
        } else {
          // this is an output port
          Operator myOperator =
              clonedOperatorsByName.get(
                  originalSource.getPorts().getOwner().getOperator().getName());
          if (myOperator == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding source for "
                    + originalSource
                    + " not found (no such operator).");
          }
          mySource = myOperator.getOutputPorts().getPortByName(originalSource.getName());
          if (mySource == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding source for "
                    + originalSource
                    + " not found (no such output port).");
          }
        }

        InputPort originalDestination = originalSource.getDestination();
        InputPort myDestination;
        if (originalDestination.getPorts().getOwner().getOperator()
            == originalExecutionUnit.getEnclosingOperator()) {
          // this is an inner sink
          myDestination = getInnerSinks().getPortByName(originalDestination.getName());
          if (myDestination == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding destination for "
                    + originalDestination
                    + " not found (no such inner sink).");
          }
        } else {
          // this is an input port
          Operator myOperator =
              clonedOperatorsByName.get(
                  originalDestination.getPorts().getOwner().getOperator().getName());
          if (myOperator == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding destination for "
                    + originalDestination
                    + " not found (no such operator).");
          }
          myDestination = myOperator.getInputPorts().getPortByName(originalDestination.getName());
          if (myDestination == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding destination for "
                    + originalDestination
                    + " not found (no such input port).");
          }
        }
        mySource.connectTo(myDestination);
      }
    }
  }