/**
   * Builds the SRA elements that are related to this ISATAB assay. It adds runs and an experiment
   * to the respective set.
   *
   * @return true if it could successfully build the exported items.
   */
  protected boolean buildExportedAssay(
      Assay assay,
      SubmissionType.FILES xsubFiles,
      RunSetType xrunSet,
      ExperimentSetType xexperimentSet,
      SampleSetType xsampleSet) {
    String assayAcc = assay.getAcc();

    // Now create an experiment for the input material and link it to the run

    // get Material associated to the assay and get its identifier
    Material material = assay.getMaterial();
    String materialAcc = material.getAcc();

    // create a new SRA Experiment and assign ISA Material name as SRA Experiment Title
    ExperimentType xexp = ExperimentType.Factory.newInstance();
    xexp.setAlias(materialAcc);
    xexp.setTITLE("experiment made with the sample " + material.getName());

    xexp.setCenterName(centerName);
    xexp.setBrokerName(brokerName);

    PlatformType xplatform = buildExportedPlatform(assay);
    if (xplatform == null) {
      return false;
    }
    xexp.setPLATFORM(xplatform);

    xexp.setPROCESSING(buildExportedProcessing(assay));

    STUDYREF xstudyRef = STUDYREF.Factory.newInstance();
    xstudyRef.setRefname(assay.getStudy().getAcc());
    xexp.setSTUDYREF(xstudyRef);
    EXPERIMENTREF xexpRef = EXPERIMENTREF.Factory.newInstance();
    xexpRef.setRefname(materialAcc);

    DESIGN xdesign = DESIGN.Factory.newInstance();
    xdesign.setDESIGNDESCRIPTION("See study and sample descriptions for details");

    SAMPLEDESCRIPTOR xsampleRef = buildExportedAssaySample(assay, xsampleSet);
    if (xsampleRef == null) {
      return false;
    }

    xdesign.setSAMPLEDESCRIPTOR(xsampleRef);

    LIBRARYDESCRIPTOR xlib = buildExportedLibraryDescriptor(assay);
    if (xlib == null) {
      return false;
    }
    xdesign.setLIBRARYDESCRIPTOR(xlib);

    SpotDescriptorType xspotd = buildExportedSpotDescriptor(assay);
    if (xspotd == null) {
      return false;
    }

    xdesign.setSPOTDESCRIPTOR(xspotd);

    xexp.setDESIGN(xdesign);

    // For each file, builds one run, with one data block and one file
    // TODO: We should introduce something like "Run Name", so that multiple files associated to a
    // single run can be
    // specified
    //
    for (AssayResult ar : ProcessingUtils.findAssayResultsFromAssay(assay)) {
      Data data = ar.getData();
      String url = StringUtils.trimToNull(data.getUrl());
      Study study = ar.getStudy();

      if (url == null) {
        String msg =
            MessageFormat.format(
                "The assay file of type {0} / {1} for study {2} has a data file node without file name, ignoring",
                assay.getMeasurement().getName(),
                assay.getTechnologyName(),
                assay.getStudy().getAcc());
        nonRepeatedMessages.add(msg + ". Data node is " + data.getName());
        log.trace(msg);
        return false;
      }

      FILE.Filetype.Enum xfileType = null;
      String fileType =
          StringUtils.trimToNull(data.getSingleAnnotationValue("comment:SRA File Type"));
      if (fileType == null) {
        // Let's try to get it from the file extension
        //
        fileType = StringUtils.trimToNull(FilenameUtils.getExtension(url));
        if (fileType != null) {
          xfileType = FILE.Filetype.Enum.forString(fileType.toLowerCase());
        }

        if (xfileType == null) {
          String msg =
              MessageFormat.format(
                  "The assay file of type {0} / {1} for study {2} has a data file node without the annotation "
                      + "'SRA file type' and I cannot compute the file type from the file name, ignoring the assay",
                  assay.getMeasurement().getName(),
                  assay.getTechnologyName(),
                  assay.getStudy().getAcc());
          nonRepeatedMessages.add(msg);
          log.trace(msg + ". Data node is " + data.getName());
          return false;
        }
      }

      if (xfileType == null) {
        // fileType is certainly non null at this point, cause it was explicitly provided and so we
        // have to process it
        //
        xfileType = FILE.Filetype.Enum.forString(fileType.toLowerCase());

        if (xfileType == null) {
          String msg =
              MessageFormat.format(
                  "The assay file of type {0} / {1} for study {2} has a bad 'SRA File Type' annotation: '"
                      + fileType
                      + "'"
                      + ", ignoring the assy",
                  assay.getMeasurement().getName(),
                  assay.getTechnologyName(),
                  assay.getStudy().getAcc());
          nonRepeatedMessages.add(msg);
          log.trace(msg + ". Data node is " + data.getName());
          return false;
        }
      }

      RunType xrun = RunType.Factory.newInstance();
      xrun.setAlias(assayAcc);
      xrun.setCenterName(centerName);
      xrun.setBrokerName(brokerName);

      DATABLOCK dataBlock = DATABLOCK.Factory.newInstance();
      FILES xfiles = FILES.Factory.newInstance();
      FILE xfile = FILE.Factory.newInstance();
      xfile.setFiletype(xfileType);
      xfile.setFilename(url);
      xfiles.addNewFILE();
      xfiles.setFILEArray(0, xfile);
      dataBlock.setFILES(xfiles);
      xrun.addNewDATABLOCK();
      xrun.setDATABLOCKArray(xrun.sizeOfDATABLOCKArray() - 1, dataBlock);

      addExportedSubmissionFile(xsubFiles, url);
      // TODO: remove, it's deprecated now xrun.setTotalDataBlocks ( BigInteger.ONE );
      xrun.setEXPERIMENTREF(xexpRef);

      xrunSet.addNewRUN();
      xrunSet.setRUNArray(xrunSet.sizeOfRUNArray() - 1, xrun);
    }

    xexperimentSet.addNewEXPERIMENT();
    xexperimentSet.setEXPERIMENTArray(xexperimentSet.sizeOfEXPERIMENTArray() - 1, xexp);
    return true;
  }