/** Creates an input gate and all of its input channels. */
  public static SingleInputGate create(
      String owningTaskName,
      JobID jobId,
      ExecutionAttemptID executionId,
      InputGateDeploymentDescriptor igdd,
      NetworkEnvironment networkEnvironment) {

    final IntermediateDataSetID consumedResultId = checkNotNull(igdd.getConsumedResultId());

    final int consumedSubpartitionIndex = igdd.getConsumedSubpartitionIndex();
    checkArgument(consumedSubpartitionIndex >= 0);

    final InputChannelDeploymentDescriptor[] icdd =
        checkNotNull(igdd.getInputChannelDeploymentDescriptors());

    final SingleInputGate inputGate =
        new SingleInputGate(
            owningTaskName,
            jobId,
            executionId,
            consumedResultId,
            consumedSubpartitionIndex,
            icdd.length,
            networkEnvironment.getPartitionStateChecker());

    // Create the input channels. There is one input channel for each consumed partition.
    final InputChannel[] inputChannels = new InputChannel[icdd.length];

    for (int i = 0; i < inputChannels.length; i++) {

      final ResultPartitionID partitionId = icdd[i].getConsumedPartitionId();
      final ResultPartitionLocation partitionLocation = icdd[i].getConsumedPartitionLocation();

      if (partitionLocation.isLocal()) {
        inputChannels[i] =
            new LocalInputChannel(
                inputGate,
                i,
                partitionId,
                networkEnvironment.getPartitionManager(),
                networkEnvironment.getTaskEventDispatcher(),
                networkEnvironment.getPartitionRequestInitialAndMaxBackoff());
      } else if (partitionLocation.isRemote()) {
        inputChannels[i] =
            new RemoteInputChannel(
                inputGate,
                i,
                partitionId,
                partitionLocation.getConnectionId(),
                networkEnvironment.getConnectionManager(),
                networkEnvironment.getPartitionRequestInitialAndMaxBackoff());
      } else if (partitionLocation.isUnknown()) {
        inputChannels[i] =
            new UnknownInputChannel(
                inputGate,
                i,
                partitionId,
                networkEnvironment.getPartitionManager(),
                networkEnvironment.getTaskEventDispatcher(),
                networkEnvironment.getConnectionManager(),
                networkEnvironment.getPartitionRequestInitialAndMaxBackoff());
      } else {
        throw new IllegalStateException("Unexpected partition location.");
      }

      inputGate.setInputChannel(partitionId.getPartitionId(), inputChannels[i]);
    }

    LOG.debug("Created input channels {} from {}.", Arrays.toString(inputChannels), igdd);

    return inputGate;
  }