@Override
 public void performOperation(
     AnnotatedPluginDocument[] annotatedDocuments,
     ProgressListener progressListener,
     Options options,
     SequenceSelection sequenceSelection,
     OperationCallback callback)
     throws DocumentOperationException {
   try {
     String[] urnStrings = options.getValueAsString(URNS_OPTION_NAME).split("\n");
     List<URN> validUrns = new ArrayList<URN>();
     List<String> brokenUrns = new ArrayList<String>();
     List<URN> missingUrns = new ArrayList<URN>();
     for (String urnString : urnStrings) {
       try {
         String trimmedString = urnString.trim();
         if (trimmedString.isEmpty()) {
           continue;
         }
         URN urn = new URN(trimmedString);
         if (DocumentUtilities.getDocumentByURN(urn) == null) {
           missingUrns.add(urn);
           continue;
         }
         validUrns.add(urn);
       } catch (MalformedURNException e) {
         brokenUrns.add(urnString);
       }
     }
     if (!brokenUrns.isEmpty()) {
       if (!Dialogs.showContinueCancelDialog(
           "Some of the URNs you entered are invalid. They will be ignored:\n\n"
               + StringUtilities.join("\n", brokenUrns),
           "Invalid URNs",
           null,
           Dialogs.DialogIcon.INFORMATION)) {
         return;
       }
     }
     if (!missingUrns.isEmpty()) {
       if (!Dialogs.showContinueCancelDialog(
           "Some of the URNs you entered cannot be found. They will be ignored:\n\n"
               + StringUtilities.join("\n", missingUrns),
           "Missing URNs",
           null,
           Dialogs.DialogIcon.INFORMATION)) {
         return;
       }
     }
     DocumentUtilities.selectDocuments(validUrns);
   } finally {
     progressListener.setProgress(1.0);
   }
 }
  /**
   * Utility method for building a matrix of distances based on a calculator for each pairwise
   * sequence distance
   *
   * @throws CannotBuildDistanceMatrixException only if
   *     useTwiceMaximumDistanceWhenPairwiseDistanceNotCalculatable is false
   */
  protected static double[][] buildDistancesMatrix(
      PairwiseDistanceCalculator pairwiseDistanceCalculator,
      int dimension,
      boolean useTwiceMaximumDistanceWhenPairwiseDistanceNotCalculatable,
      ProgressListener progress)
      throws CannotBuildDistanceMatrixException {
    double[][] distances = new double[dimension][dimension];

    float tot = (dimension * (dimension - 1)) / 2;
    int done = 0;
    final double noDistance = -1;
    double maxDistance = -1;
    for (int i = 0; i < dimension; ++i) {
      for (int j = i + 1; j < dimension; ++j) {
        try {
          distances[i][j] = pairwiseDistanceCalculator.calculatePairwiseDistance(i, j);
          maxDistance = Math.max(distances[i][j], maxDistance);
        } catch (CannotBuildDistanceMatrixException e) {
          if (!useTwiceMaximumDistanceWhenPairwiseDistanceNotCalculatable) {
            throw e;
          }
          distances[i][j] = noDistance;
        }
        distances[j][i] = distances[i][j];
        if (progress != null) progress.setProgress(++done / tot);
      }
    }
    if (maxDistance < 0) {
      throw new CannotBuildDistanceMatrixException(
          "It is not possible to compute the Tamura-Nei genetic distance "
              + "for these sequences because no pair of sequences overlap in the alignment.");
    }
    for (int i = 0; i < dimension; ++i) {
      for (int j = i + 1; j < dimension; ++j) {
        if (distances[i][j] == noDistance) {
          distances[i][j] = distances[j][i] = maxDistance * 2;
        }
      }
    }
    return distances;
  }