private void associateWithBuildRun(
      BuildRun buildRun, Collection<ChangeSet> changeSets, Set<PrimaryWorkitem> workitems) {
    for (ChangeSet changeSet : changeSets) {
      buildRun.getChangeSets().add(changeSet);
      for (PrimaryWorkitem workitem : workitems) {
        if (workitem.isClosed()) {
          logger.println(MessagesRes.workitemClosedCannotAttachData(workitem.getDisplayID()));
          continue;
        }

        final Collection<BuildRun> completedIn = workitem.getCompletedIn();
        final List<BuildRun> toRemove = new ArrayList<BuildRun>(completedIn.size());

        changeSet.getPrimaryWorkitems().add(workitem);

        for (BuildRun otherRun : completedIn) {
          if (otherRun.getBuildProject().equals(buildRun.getBuildProject())) {
            toRemove.add(otherRun);
          }
        }

        for (BuildRun buildRunDel : toRemove) {
          completedIn.remove(buildRunDel);
        }

        completedIn.add(buildRun);
      }
    }
  }
  private Set<PrimaryWorkitem> determineWorkitems(String comment) {
    List<String> ids = getWorkitemsIds(comment, config.pattern);
    Set<PrimaryWorkitem> result = new HashSet<PrimaryWorkitem>(ids.size());

    for (String id : ids) {
      result.addAll(getPrimaryWorkitemsByReference(id));
    }
    return result;
  }
  /**
   * Return list of workitems got from the comment string.
   *
   * @param comment string with some text with ids of tasks which cut using pattern set in the
   *     referenceexpression attribute.
   * @param v1PatternCommit regular expression for comment parse and getting data from it.
   * @return list of cut ids.
   */
  public static List<String> getWorkitemsIds(String comment, Pattern v1PatternCommit) {
    final List<String> result = new LinkedList<String>();

    if (v1PatternCommit != null) {
      Matcher m = v1PatternCommit.matcher(comment);
      while (m.find()) {
        result.add(m.group());
      }
    }

    return result;
  }
  /**
   * Resolve a check-in comment identifier to a PrimaryWorkitem. if the reference matches a
   * SecondaryWorkitem, we need to navigate to the parent.
   *
   * @param reference The identifier in the check-in comment.
   * @return A collection of matching PrimaryWorkitems.
   */
  private List<PrimaryWorkitem> getPrimaryWorkitemsByReference(String reference) {
    List<PrimaryWorkitem> result = new ArrayList<PrimaryWorkitem>();

    WorkitemFilter filter = new WorkitemFilter();
    filter.find.setSearchString(reference);
    filter.find.fields.add(config.referenceField);
    Collection<Workitem> workitems = config.getV1Instance().get().workitems(filter);
    for (Workitem workitem : workitems) {
      if (workitem instanceof PrimaryWorkitem) {
        result.add((PrimaryWorkitem) workitem);
      } else if (workitem instanceof SecondaryWorkitem) {
        result.add(((SecondaryWorkitem) workitem).getParent());
      } else {
        throw new RuntimeException("Found unexpected Workitem type: " + workitem.getClass());
      }
    }

    return result;
  }