@Override
 protected List<TTDataSet> perform() throws TaskExecutionException, InterruptedException {
   Preconditions.checkNotNull(sources);
   List<TTDataSet> datasets = new ArrayList<TTDataSet>(sources.size());
   for (TTDataSet dataset : sources) {
     try {
       GenericTTDataBuilder builder = new GenericTTDataBuilder();
       if (getName() == null) {
         builder.setName(dataset.getName());
       } else {
         builder.setName(getName());
       }
       for (Map.Entry<String, Object> entry : dataset.getAttributes().entrySet()) {
         builder.setAttribute(entry.getKey(), entry.getValue());
       }
       builder.setAttribute("Retain", retain);
       builder.setQuery(dataset.getQueryData());
       builder.setTest(dataset.getTestData());
       builder.setTrain(
           downsample(dataset.getTrainingData(), dataset.getTestData().getUserDAO().getUserIds()));
       datasets.add(builder.build());
     } catch (IOException e) {
       throw new TaskExecutionException(e);
     }
   }
   return datasets;
 }
  /**
   * Prefix a table for a particular algorithmInfo and data set.
   *
   * @param base The table to prefix.
   * @param algorithm The algorithmInfo to prefix for.
   * @param dataSet The data set to prefix for.
   * @return A prefixed table, suitable for outputting the results of evaluating {@code
   *     algorithmInfo} on {@code dataSet}, or {@code null} if {@code base} is null.
   */
  public TableWriter prefixTable(TableWriter base, Attributed algorithm, TTDataSet dataSet) {
    if (base == null) {
      return null;
    }

    Object[] prefix = new Object[getCommonColumnCount()];
    prefix[0] = algorithm.getName();
    for (Map.Entry<String, Object> attr : dataSet.getAttributes().entrySet()) {
      int idx = getDataColumn(attr.getKey());
      prefix[idx] = attr.getValue();
    }
    for (Map.Entry<String, Object> attr : algorithm.getAttributes().entrySet()) {
      int idx = getAlgorithmColumn(attr.getKey());
      prefix[idx] = attr.getValue();
    }
    return TableWriters.prefixed(base, prefix);
  }