public TransparentlyFailedValueI<Map<String, Map<String, CharSequence>>, PatchSyntaxException>
      getAdditionalInfo(final Set<String> filterByPaths) {
    final TransparentlyFailedValue<Map<String, Map<String, CharSequence>>, PatchSyntaxException>
        value =
            new TransparentlyFailedValue<
                Map<String, Map<String, CharSequence>>, PatchSyntaxException>();

    final Map<String, Map<String, CharSequence>> map = myAdditionalInfoParser.getResultMap();
    final Map<String, Map<String, CharSequence>> newMap =
        new HashMap<String, Map<String, CharSequence>>();

    for (Map.Entry<String, Map<String, CharSequence>> entry : map.entrySet()) {
      final Map<String, CharSequence> innerMap = entry.getValue();
      if (filterByPaths == null || filterByPaths.contains(entry.getKey())) {
        newMap.put(entry.getKey(), innerMap);
      }
    }
    value.set(newMap);
    final PatchSyntaxException e = myAdditionalInfoParser.getSyntaxException();
    if (e != null) {
      value.fail(e);
    }
    return value;
  }
 @Nullable
 public CharSequence getBaseRevision(final Project project, final String relativeFilePath) {
   final Map<String, Map<String, CharSequence>> map = myAdditionalInfoParser.getResultMap();
   if (!map.isEmpty()) {
     final Map<String, CharSequence> inner = map.get(relativeFilePath);
     if (inner != null) {
       final BaseRevisionTextPatchEP baseRevisionTextPatchEP =
           Extensions.findExtension(PatchEP.EP_NAME, project, BaseRevisionTextPatchEP.class);
       if (baseRevisionTextPatchEP != null) {
         return inner.get(baseRevisionTextPatchEP.getName());
       }
     }
   }
   return null;
 }
  public void parseAllPatches() throws PatchSyntaxException {
    final ListIterator<String> iterator = myLines.listIterator();
    if (!iterator.hasNext()) {
      myPatches = Collections.emptyList();
      return;
    }

    String next;
    boolean containsAdditional = false;
    while (iterator.hasNext()) {
      next = iterator.next();
      final boolean containsAdditionalNow = myAdditionalInfoParser.testIsStart(next);
      if (containsAdditionalNow && containsAdditional) {
        myAdditionalInfoParser.acceptError(
            new PatchSyntaxException(
                iterator.previousIndex(), "Contains additional information without patch itself"));
      }
      if (containsAdditionalNow) {
        containsAdditional = containsAdditionalNow;
        myAdditionalInfoParser.parse(next, iterator);
        if (!iterator.hasNext()) {
          myAdditionalInfoParser.acceptError(
              new PatchSyntaxException(
                  iterator.previousIndex(),
                  "Contains additional information without patch itself"));
          break;
        }
        next = iterator.next();
      }

      if (myPatchContentParser.testIsStart(next)) {
        myPatchContentParser.parse(next, iterator);
        // iterator.previous();  // to correctly initialize next
        if (containsAdditional) {
          final String lastName = myPatchContentParser.getLastName();
          if (lastName == null) {
            myAdditionalInfoParser.acceptError(
                new PatchSyntaxException(
                    iterator.previousIndex(),
                    "Contains additional information without patch itself"));
          } else {
            myAdditionalInfoParser.copyToResult(lastName);
          }
        }
        containsAdditional = false;
      }
    }
    myPatches = myPatchContentParser.getResult();
  }