Program: 29421
Project: 29421
Buggy source:
/** 
 * A method that should be called after we visit a control flow node (  {@code IfNode} or {@code SwitchNode}). <p>Compared to   {@code matchOrError} methods, this method does not report an error when one ofthe deques is empty. However, if both deques are not empty but the top do not match, we should report an error. <p>Another difference is that we don't try to remove all optional tags from the openStack, if the closeQueue is empty. It is possible that some of the optional tags are ended in another control block, and we cannot remove them too eagerly. <p>After calling this method, <ul> <li>if it returns true, at least one of the stack/queue will be empty. <li>if it returns false, we have already reported an error. </ul>
 */
static boolean tryMatchOrError(ArrayDeque<HtmlTagEntry> openStack,ArrayDeque<HtmlTagEntry> closeQueue,ErrorReporter errorReporter){
  while (!openStack.isEmpty() && !closeQueue.isEmpty()) {
    HtmlTagEntry openTag=openStack.peekFirst();
    HtmlTagEntry closeTag=closeQueue.peekFirst();
    if (closeTag.isDefinitelyOptional()) {
      if (closeTag.getTagName().equals(openTag.getTagName())) {
        openStack.pollFirst();
        closeQueue.pollFirst();
        continue;
      }
      if (!openTag.hasTagName()) {
        if (tryMatchCommonPrefix(openTag,closeTag,errorReporter)) {
          openStack.pollFirst();
          closeQueue.pollFirst();
          continue;
        }
        errorReporter.report(closeTag.getSourceLocation(),UNEXPECTED_CLOSE_TAG);
        return false;
      }
    }
    if (closeTag.hasTagName()) {
      openTag=popOptionalTags(openStack);
    }
    if (matchOrError(openTag,closeTag,errorReporter)) {
      openStack.pollFirst();
      closeQueue.pollFirst();
    }
 else {
      return false;
    }
  }
  return true;
}

Fixed version (ground truth):
/** 
 * A method that should be called after we visit a control flow node (  {@code IfNode} or {@code SwitchNode}). <p>Compared to   {@code matchOrError} methods, this method does not report an error when one ofthe deques is empty. However, if both deques are not empty but the top do not match, we should report an error. <p>Another difference is that we don't try to remove all optional tags from the openStack, if the closeQueue is empty. It is possible that some of the optional tags are ended in another control block, and we cannot remove them too eagerly. <p>After calling this method, <ul> <li>if it returns true, at least one of the stack/queue will be empty. <li>if it returns false, we have already reported an error. </ul>
 */
static boolean tryMatchOrError(ArrayDeque<HtmlTagEntry> openStack,ArrayDeque<HtmlTagEntry> closeQueue,ErrorReporter errorReporter){
  while (!openStack.isEmpty() && !closeQueue.isEmpty()) {
    HtmlTagEntry openTag=openStack.peekFirst();
    HtmlTagEntry closeTag=closeQueue.peekFirst();
    if (closeTag.hasTagName()) {
      if (closeTag.getTagName().equals(openTag.getTagName())) {
        openStack.pollFirst();
        closeQueue.pollFirst();
        continue;
      }
 else {
        if (openTag.isDefinitelyOptional()) {
          openStack.pollFirst();
          continue;
        }
 else         if (!openTag.hasTagName()) {
          openTag.getBranches().popOptionalTags();
          if (openTag.getBranches().isEmpty()) {
            openStack.pollFirst();
            continue;
          }
          if (tryMatchCommonPrefix(openTag,closeTag,errorReporter)) {
            openStack.pollFirst();
            closeQueue.pollFirst();
            continue;
          }
          return false;
        }
      }
      openTag=popOptionalTags(openStack);
    }
    if (matchOrError(openTag,closeTag,errorReporter)) {
      openStack.pollFirst();
      closeQueue.pollFirst();
    }
 else {
      return false;
    }
  }
  return true;
}