private void createEdge(final Interaction itr, final CySubNetwork subNetwork) {
    CyNode sourceNode = nMap.get(itr.getSource());
    if (sourceNode == null) {
      sourceNode = subNetwork.addNode();
      subNetwork.getRow(sourceNode).set(CyNetwork.NAME, itr.getSource());
      nMap.put(itr.getSource(), subNetwork.getRootNetwork().getNode(sourceNode.getSUID()));
    }

    for (final String target : itr.getTargets()) {
      CyNode targetNode = nMap.get(target);
      if (targetNode == null) {
        targetNode = subNetwork.addNode();
        subNetwork.getRow(targetNode).set(CyNetwork.NAME, target);
        nMap.put(target, subNetwork.getRootNetwork().getNode(targetNode.getSUID()));
      }

      // Add the sourceNode and targetNode to subNetwork
      if (!subNetwork.containsNode(sourceNode)) {
        subNetwork.addNode(sourceNode);
      }
      if (!subNetwork.containsNode(targetNode)) {
        subNetwork.addNode(targetNode);
      }

      final CyEdge edge = subNetwork.addEdge(sourceNode, targetNode, true);
      subNetwork.getRow(edge).set(CyNetwork.NAME, getEdgeName(itr, target));
      subNetwork.getRow(edge).set(CyEdge.INTERACTION, itr.getType());
    }
  }
  private void readInput(TaskMonitor tm) throws IOException {
    this.parentTaskMonitor = tm;
    tm.setProgress(0.0);

    String line;
    final BufferedReader br =
        new BufferedReader(
            new InputStreamReader(inputStream, Charset.forName("UTF-8").newDecoder()), 128 * 1024);

    String networkCollectionName = this.rootNetworkList.getSelectedValue().toString();

    CySubNetwork subNetwork;
    if (networkCollectionName.equalsIgnoreCase(CRERATE_NEW_COLLECTION_STRING)) {
      // This is a new network collection, create a root network and a subnetwork, which is a base
      // subnetwork
      CyNetwork rootNetwork = cyNetworkFactory.createNetwork();
      subNetwork = this.cyRootNetworkManager.getRootNetwork(rootNetwork).addSubNetwork();
    } else {
      // Add a new subNetwork to the given collection
      subNetwork = this.name2RootMap.get(networkCollectionName).addSubNetwork();
    }

    // Build a Map based on the key attribute for the entire collection,
    // For SIF network, the 'shared name' attribute is the primary key
    this.initNodeMap(subNetwork.getRootNetwork(), "shared " + CyNetwork.NAME);

    tm.setProgress(0.1);

    // Generate bundled event to avoid too many events problem.

    final String firstLine = br.readLine();
    if (firstLine.contains(TAB)) delimiter = TAB;
    createEdge(new Interaction(firstLine.trim(), delimiter), subNetwork);

    tm.setProgress(0.15);
    tm.setStatusMessage("Processing the interactions...");
    int numInteractionsRead = 0;
    while ((line = br.readLine()) != null) {
      if (cancelled) {
        // Cancel called. Clean up the garbage.
        nMap.clear();
        nMap = null;
        subNetwork = null;
        br.close();
        return;
      }

      if (line.trim().length() <= 0) continue;

      try {
        final Interaction itr = new Interaction(line, delimiter);
        createEdge(itr, subNetwork);
      } catch (Exception e) {
        // Simply ignore invalid lines.
        continue;
      }

      if ((++numInteractionsRead % 1000) == 0)
        tm.setStatusMessage("Processed " + numInteractionsRead + " interactions so far.");
    }

    br.close();
    tm.setStatusMessage("Processed " + numInteractionsRead + " interactions in total.");

    nMap.clear();
    nMap = null;

    this.cyNetworks = new CyNetwork[] {subNetwork};

    tm.setProgress(1.0);

    logger.debug("SIF file loaded: ID = " + subNetwork.getSUID());
  }