docs: private boolean goToNextDoc() throws IOException {
      if (docId == NO_MORE_DOCS) {
        return true;
      } else {
        // try to find docId with match for all items from sequence
        Integer spanDocId;
        Integer newDocId = null;
        Integer minOptionalDocId = null;
        boolean allItemsOptional = true;
        for (QueueItem item : queueSpans) {
          if (!item.sequenceSpans.optional) {
            allItemsOptional = false;
          }
          if (!item.noMoreDocs) {
            if (item.sequenceSpans.spans == null) {
              spanDocId = NO_MORE_DOCS;
            } else if (newDocId == null) {
              spanDocId = item.sequenceSpans.spans.nextDoc();
            } else {
              if (!item.sequenceSpans.optional) {
                spanDocId = item.sequenceSpans.spans.advance(newDocId);
              } else {
                if (item.sequenceSpans.spans.docID() == -1
                    || newDocId > item.sequenceSpans.spans.docID()) {
                  spanDocId = item.sequenceSpans.spans.advance(newDocId);
                } else {
                  spanDocId = item.sequenceSpans.spans.docID();
                }
              }
            }
            if (spanDocId.equals(NO_MORE_DOCS)) {
              item.noMoreDocs = true;
              if (!item.sequenceSpans.optional) {
                // a not optional span has NO_MORE_DOCS: stop
                docId = NO_MORE_DOCS;
                return true;
              }
            } else if (!spanDocId.equals(newDocId)) {
              // last found spanDocId not equal to potential new docId
              if (newDocId != null) {
                if (!item.sequenceSpans.optional) {
                  // move also previous spans to at least spanDocId
                  advance(spanDocId);
                  return true;
                }
                // define potential new docId
              } else {
                if (!item.sequenceSpans.optional) {
                  // previous optional span with lower docId
                  if ((minOptionalDocId != null)
                      && (minOptionalDocId < spanDocId)) {
                    advance(spanDocId);
                    return true;
                  } else {
                    // use spanDocId as potential newDocId
                    newDocId = spanDocId;
                  }
                } else {
                  // remember minimum docId optional spans
                  minOptionalDocId = (minOptionalDocId == null) ? spanDocId
                      : Math.min(minOptionalDocId, spanDocId);
                }
              }
            }
          }
        }
        // if all items are optional
        if (allItemsOptional && newDocId == null && minOptionalDocId != null) {
          newDocId = minOptionalDocId;
        }
        // nothing found
        if (newDocId == null) {
          docId = NO_MORE_DOCS;
          return true;
        } else {
          docId = newDocId;
          ignoreItem.advanceToDoc(docId);
          // try and glue together
          if (findMatches()) {
            return true;
            // no matches
          } else {
            resetQueue();
            return false;
          }
        }
      }
    }