public void mapEdgeColumn(final EncoreInteraction interaction, final CyRow row) {

    final Set<String> exp = interaction.getExperimentToPubmed().keySet();
    row.set(DETECTION_METHOD_ID, new ArrayList<String>(exp));

    final List<CrossReference> pubIDs = interaction.getPublicationIds();
    final List<String> pubIdList = new ArrayList<String>();
    final List<String> pubDBList = new ArrayList<String>();
    for (CrossReference pub : pubIDs) {
      pubIdList.add(pub.getIdentifier());
      pubDBList.add(pub.getDatabase());
    }
    if (pubIdList.isEmpty() == false) row.set(PUB_ID, pubIdList);
    if (pubDBList.isEmpty() == false) row.set(PUB_DB, pubDBList);

    // Interaction (use UniqueID)
    row.set(CyEdge.INTERACTION, interaction.getMappingIdDbNames());

    final List<Confidence> scores = interaction.getConfidenceValues();
    for (Confidence c : scores) {
      String type = c.getType();
      String value = c.getValue();

      if (row.getTable().getColumn(type) == null)
        row.getTable().createColumn(type, Double.class, true);

      try {
        double doubleVal = Double.parseDouble(value);
        row.set(type, doubleVal);
      } catch (NumberFormatException e) {
        // logger.warn("Invalid number string: " + value);
        // Ignore invalid number
      }
    }
  }
  /**
   * Add a single entry
   *
   * @param row
   * @param val
   * @param columnName
   */
  private final void addSingleColumn(
      final CyRow row, final String val, final String columnName, final Class<?> dataType) {
    // Ignore invalid entry.
    if (val == null || val.equals("-")) {
      return;
    }

    // Create column if necessary
    if (row.getTable().getColumn(columnName) == null) {
      row.getTable().createColumn(columnName, dataType, false);
    }

    Object newValue = val;
    if (dataType == Boolean.class) newValue = Boolean.parseBoolean(val);

    row.set(columnName, newValue);
  }
  private void processOtherNames(CyRow row, final Map<String, List<String>> accs) {
    for (String originalDBName : accs.keySet()) {

      final String dbName = validateNamespace(originalDBName);

      if (row.getTable().getColumn(dbName) == null)
        row.getTable().createListColumn(dbName, String.class, false);

      List<String> currentList = row.getList(dbName, String.class);
      if (currentList == null) currentList = new ArrayList<String>();

      final Set<String> nameSet = new HashSet<String>(currentList);
      final List<String> names = accs.get(originalDBName);
      nameSet.addAll(names);
      row.set(dbName, new ArrayList<String>(nameSet));
    }
  }
  private void guessHumanReadableName(final CyRow row) {
    boolean found = false;

    // Special handler for STRING. This is a hack...
    if (row.getTable().getColumn(STRING_ATTR_NAME) != null) {
      final List<String> stringList = row.getList(STRING_ATTR_NAME, String.class);
      if (stringList != null) found = findHumanReadableName(row, stringList, ncbiPattern, true);
    }

    if (found) return;

    // try NCBI
    if (row.getTable().getColumn(ENTREZ_GENE_ATTR_NAME) != null) {
      final List<String> ncbiList = row.getList(ENTREZ_GENE_ATTR_NAME, String.class);
      if (ncbiList != null) found = findHumanReadableName(row, ncbiList, ncbiPattern, true);
    }
    if (found) return;

    // Try Uniprot
    List<String> uniprotList = null;
    if (row.getTable().getColumn(UNIPROT_ATTR_NAME) != null) {
      uniprotList = row.getList(UNIPROT_ATTR_NAME, String.class);
      if (uniprotList != null) found = findHumanReadableName(row, uniprotList, exact1Pattern, true);
    }
    if (found) return;

    if (uniprotList != null) found = findHumanReadableName(row, uniprotList, uniprotPattern, false);

    if (found) return;

    // Unknown
    if (row.getTable().getColumn("unknown") != null) {
      final List<String> unknownList = row.getList("unknown", String.class);
      if (unknownList != null)
        found = findHumanReadableName(row, unknownList, uniprotPattern, false);
    }
    if (found) return;

    if (found == false) {
      // Give up. Use primary key
      row.set(PREDICTED_GENE_NAME, row.get(CyNetwork.NAME, String.class));
    }
  }
  /**
   * Split the entry by the delimiter and simply creates list column from the values.
   *
   * @param row
   * @param val
   * @param columnName
   */
  private final void addSimpleListColumn(
      final CyRow row, final String val, final String columnName) {
    // Ignore invalid entry.
    if (val == null || val.equals("-")) {
      return;
    }

    // Create column if necessary
    if (row.getTable().getColumn(columnName) == null) {
      row.getTable().createListColumn(columnName, String.class, false);
    }

    final String[] entries = SPLITTER.split(val);
    final List<String> ids = new ArrayList<String>();
    for (final String entry : entries) {
      if (entry != null) {
        final String newEntry = entry.replaceAll("\"", "");
        ids.add(newEntry);
      }
    }
    if (!ids.isEmpty()) row.set(columnName, ids);
  }
  private final void addListColumn(
      final CyRow row, final String val, final String columnName, final Class<?> listType) {
    if (val == null || val.equals("-")) {
      return;
    }

    String newColName = null;

    // Create column if necessary
    if (columnName != null) {
      if (row.getTable().getColumn(columnName) == null) {
        row.getTable().createListColumn(columnName, listType, false);
        row.getTable().createListColumn(columnName + " ID", String.class, false);
      }
      newColName = columnName;
    }

    final String[] entries = SPLITTER.split(val);

    final List<String> ids = new ArrayList<String>();
    final List<String> descriptions = new ArrayList<String>();
    for (final String entry : entries) {
      final String[] contents = parseValues(entry);
      if (newColName == null) {
        if (row.getTable().getColumn(contents[0]) == null) {
          row.getTable().createListColumn(contents[0], listType, false);
          row.getTable().createListColumn(contents[0] + " ID", String.class, false);
        }
        newColName = contents[0];
      }
      if (contents[1] != null) ids.add(contents[1]);
      if (contents[2] != null) descriptions.add(contents[2]);
    }
    if (!ids.isEmpty()) row.set(newColName + " ID", ids);
    if (!descriptions.isEmpty()) row.set(newColName, descriptions);
  }
  private void mergeRow(String keyName, CyRow sourceRow, CyRow targetRow) {
    for (CyColumn column : sourceRow.getTable().getColumns()) {
      if (cancelled) return;

      String columnName = column.getName();

      if (columnName.equals(keyName)) continue;

      Class<?> type = column.getType();

      if (type.equals(List.class)) {
        Class<?> elementType = column.getListElementType();
        List<?> list = sourceRow.getList(columnName, elementType);
        targetRow.set(columnName, list);
      } else {
        Object value = sourceRow.get(columnName, type);
        targetRow.set(columnName, value);
      }
    }
  }
  public void mapEdgeColumn(
      final String[] entries,
      final CyRow row,
      final CyEdge edge,
      final String sourceName,
      final String targetName) {

    // Column 7: Detection method
    final String[] detectionMethods = SPLITTER.split(entries[6]);
    final List<String> methods = new ArrayList<String>();
    final List<String> methodID = new ArrayList<String>();
    for (final String entry : detectionMethods) {
      final String[] methodContents = parseValues(entry);
      if (methodContents[1] != null) methodID.add(methodContents[1]);
      if (methodContents[2] != null) methods.add(methodContents[2]);
    }
    if (!methods.isEmpty()) row.set(DETECTION_METHOD_NAME, methods);
    if (!methodID.isEmpty()) row.set(DETECTION_METHOD_ID, methodID);

    // Column 8: Authors
    final String[] authorsParts = SPLITTER.split(entries[7]);
    final List<String> authors = new ArrayList<String>();
    for (final String entry : authorsParts) {
      String updatedAuthor = entry.replaceAll("\"", "");
      authors.add(updatedAuthor);
    }
    if (!authors.isEmpty()) row.set(AUTHOR, authors);

    final List<String> pubIdList = new ArrayList<String>();
    final List<String> pubDBList = new ArrayList<String>();
    final String[] pubID = SPLITTER.split(entries[8]);
    for (final String entry : pubID) {
      String id = parseValues(entry)[1];
      String db = parseValues(entry)[0];
      if (id != null && db != null) {
        pubDBList.add(db);
        pubIdList.add(id);
      }
    }

    if (!pubIdList.isEmpty()) row.set(PUB_ID, pubIdList);
    if (!pubDBList.isEmpty()) row.set(PUB_DB, pubDBList);

    final String[] dbNames = SPLITTER.split(entries[12]);
    row.set(SOURCE_DB, parseValues(dbNames[0])[0]);

    // Interaction Types - Use first one as primary type.
    final String[] typeParts = SPLITTER.split(entries[11]);
    final List<String> types = new ArrayList<String>();
    for (final String entry : typeParts) {
      final String type = parseValues(entry)[2];
      if (type != null) types.add(type);
    }
    if (!types.isEmpty()) {
      row.set(INTERACTION_TYPE, types);
      row.set(PRIMARY_INTERACTION_TYPE, types.get(0));
    }

    // Set interaction: this is an ID.
    final String[] interactionID = SPLITTER.split(entries[13]);
    final String interaction = parseValues(interactionID[0])[1];
    row.set(CyEdge.INTERACTION, interaction);

    // Create name
    row.set(CyNetwork.NAME, sourceName + " (" + interaction + ") " + targetName);

    final String[] scores = SPLITTER.split(entries[14]);
    for (String score : scores) {
      final String[] scoreArray = parseValues(score);
      String scoreType = "Confidence-Score-" + scoreArray[0];
      String value = scoreArray[1];
      if (value == null) {
        continue;
      }

      if (row.getTable().getColumn(scoreType) == null)
        row.getTable().createColumn(scoreType, Double.class, true);

      try {
        double doubleVal = Double.parseDouble(value);
        row.set(scoreType, doubleVal);
      } catch (NumberFormatException e) {
        // logger.warn("Invalid number string: " + value);
        // Ignore invalid number
      }
    }

    // For MITAB 2.7
    if (entries.length > 15) {
      addListColumn(row, entries[16], "Source Biological Role", String.class);
      addListColumn(row, entries[17], "Target Biological Role", String.class);
      addListColumn(row, entries[18], "Source Experimental Role", String.class);
      addListColumn(row, entries[19], "Target Experimental Role", String.class);
      addListColumn(row, entries[40], "Source Participant Detection Method", String.class);
      addListColumn(row, entries[41], "Target Participant Detection Method", String.class);

      addListColumn(row, entries[15], "Complex Expansion", String.class);
      addListColumn(row, entries[24], "Xref", String.class);

      addSimpleListColumn(row, entries[27], "Annotation");

      addListColumn(row, entries[28], "Host Organism Taxonomy", String.class);
      addSimpleListColumn(row, entries[29], "Parameters");

      addSingleColumn(row, entries[30], "Creation Date", String.class);
      addSingleColumn(row, entries[31], "Update Date", String.class);

      addSingleColumn(row, entries[35], "Negative", Boolean.class);
    }
  }