/** {@inheritDoc} */
  public void process(Reader reader) throws ObjectStoreException, IOException {

    initialiseMapsForFile();

    BufferedReader br = new BufferedReader(reader);
    String line = null;

    // loop through entire file
    while ((line = br.readLine()) != null) {
      if (line.startsWith("!")) {
        continue;
      }
      String[] array = line.split("\t", -1); // keep trailing empty Strings
      if (array.length < 13) {
        throw new IllegalArgumentException(
            "Not enough elements (should be > 13 not " + array.length + ") in line: " + line);
      }

      String taxonId = parseTaxonId(array[12]);
      Config config = configs.get(taxonId);
      if (config == null) {
        throw new NullPointerException(
            "No entry for organism with taxonId = '" + taxonId + "' found in config file.");
      }
      int readColumn = config.readColumn();
      String productId = array[readColumn];

      String goId = array[4];
      String qualifier = array[3];
      String strEvidence = array[6];
      String withText = array[7];
      if (StringUtils.isNotEmpty(strEvidence)) {
        storeEvidenceCode(strEvidence);
      } else {
        throw new IllegalArgumentException(
            "Evidence is a required column but not "
                + "found for doterm "
                + goId
                + " and productId "
                + productId);
      }

      // type of gene product, we're not interested in at the moment
      // String type = array[11];
      String type = configs.get(taxonId).annotationType;

      // Wormbase has some proteins with UniProt accessions and some with WB:WP ids,
      // hack here to get just the UniProt ones.
      // if (("protein".equalsIgnoreCase(type) && !array[0].startsWith("UniProt"))
      //        || (!"protein".equalsIgnoreCase(type) && array[0].startsWith("UniProt"))) {
      //    continue;
      // }

      // create unique key for go annotation
      GoTermToGene key = new GoTermToGene(productId, goId, qualifier);

      String dataSourceCode = array[14];
      Item organism = newOrganism(taxonId);
      String productIdentifier = newProduct(productId, type, organism, dataSourceCode, true, null);

      // null if resolver could not resolve an identifier
      if (productIdentifier != null) {

        // null if no pub found
        String pubRefId = newPublication(array[5]);

        // get evidence codes for this goterm|gene pair
        Set<Evidence> allEvidenceForAnnotation = goTermGeneToEvidence.get(key);

        // new evidence
        if (allEvidenceForAnnotation == null) {
          String goTermIdentifier = newGoTerm(goId, dataSourceCode);
          Evidence evidence = new Evidence(strEvidence, pubRefId);
          allEvidenceForAnnotation = new LinkedHashSet<Evidence>();
          allEvidenceForAnnotation.add(evidence);
          goTermGeneToEvidence.put(key, allEvidenceForAnnotation);
          Integer storedAnnotationId =
              createGoAnnotation(
                  productIdentifier,
                  type,
                  goTermIdentifier,
                  organism,
                  qualifier,
                  withText,
                  dataSourceCode);
          evidence.setStoredAnnotationId(storedAnnotationId);
        } else {
          boolean seenEvidenceCode = false;
          Integer storedAnnotationId = null;
          for (Evidence evidence : allEvidenceForAnnotation) {
            String evidenceCode = evidence.getEvidenceCode();
            // already have evidence code, just add pub
            if (evidenceCode.equals(strEvidence)) {
              evidence.addPublicationRefId(pubRefId);
              seenEvidenceCode = true;
            }
            storedAnnotationId = evidence.storedAnnotationId;
          }
          if (!seenEvidenceCode) {
            Evidence evidence = new Evidence(strEvidence, pubRefId);
            evidence.storedAnnotationId = storedAnnotationId;
            allEvidenceForAnnotation.add(evidence);
          }
        }
      }
    }
    storeProductCollections();
    storeEvidence();
  }