@Override
  protected void recursiveTokens(final Interval interval) {
    int endOffset = interval.getEndOffset();
    int startOffset = interval.getStartOffset();
    if (documentText.length() <= endOffset || documentText.length() <= startOffset) {
      return;
    } else if (endOffset == -1) {
      endOffset = documentText.length() - 1;
    }

    int distance = interval.getEndLine() - interval.getStartLine();
    if (distance >= foldingDistance) {
      char temp = documentText.charAt(startOffset);
      switch (temp) {
        case '{':
        case '[':
          if (preferencesService.getBoolean(
              ProductConstants.PRODUCT_ID_DESIGNER,
              PreferenceConstants.FOLD_STATEMENT_BLOCKS,
              true,
              null)) {
            positions.add(new Position(startOffset, endOffset - startOffset));
          }
          break;
        case '(':
          if (preferencesService.getBoolean(
              ProductConstants.PRODUCT_ID_DESIGNER,
              PreferenceConstants.FOLD_PARENTHESIS,
              true,
              null)) {
            positions.add(new Position(startOffset, endOffset - startOffset));
          }
          break;
        case '/':
          if (preferencesService.getBoolean(
              ProductConstants.PRODUCT_ID_DESIGNER,
              PreferenceConstants.FOLD_COMMENTS,
              true,
              null)) {
            positions.add(new Position(startOffset, endOffset - startOffset));
          }
          break;
        default:
          break;
      }
    }
    for (Interval subIntervall : interval.getSubIntervals()) {
      recursiveTokens(subIntervall);
    }
  }
  @Override
  public List<Position> calculatePositions(final IDocument document) {
    positions.clear();

    this.lastLineIndex = document.getNumberOfLines();
    this.documentText = document.get();
    preferencesService = Platform.getPreferencesService();
    foldingDistance =
        preferencesService.getInt(
            ProductConstants.PRODUCT_ID_DESIGNER, PreferenceConstants.FOLD_DISTANCE, 0, null);

    if (preferencesService.getBoolean(
        ProductConstants.PRODUCT_ID_DESIGNER, PreferenceConstants.FOLDING_ENABLED, true, null)) {
      Interval interval = GlobalIntervalHandler.getInterval(document);
      if (interval == null) {
        interval = (new HeuristicalIntervalDetector()).buildIntervals(document);
        GlobalIntervalHandler.putInterval(document, interval);
      }
      for (Interval subintervall : interval.getSubIntervals()) {
        recursiveTokens(subintervall);
      }
    }
    return positions;
  }
  /** Do the actual indentation work. */
  private void doIndent() {
    if (targetEditor == null) {
      return;
    }

    IDocument document = getDocument();

    if (null == document) {
      return;
    }

    Interval rootInterval = GlobalIntervalHandler.getInterval(document);
    if (rootInterval == null) {
      rootInterval = (new HeuristicalIntervalDetector()).buildIntervals(document);
      GlobalIntervalHandler.putInterval(document, rootInterval);
    }
    if (rootInterval == null) {
      return;
    }

    int startLine = -1;
    int endLine = -1;
    if (!selection.isEmpty()) {
      if (selection instanceof TextSelection) {
        TextSelection tSelection = (TextSelection) selection;
        if (tSelection.getLength() != 0) {
          startLine = tSelection.getStartLine();
          endLine = tSelection.getEndLine();
        }
      }
    }
    if (startLine == -1 || endLine == -1) {
      startLine = 0;
      endLine = document.getNumberOfLines() - 1;
    }

    indentArray.clear();
    indentArray.add("");

    int nofLines = endLine - startLine;
    int offset;
    int realOffset;
    int lineLength;
    Interval interval;
    try {
      int regionStartOffset = document.getLineOffset(startLine);
      int regionLength =
          document.getLineOffset(endLine) + document.getLineLength(endLine) - regionStartOffset;
      multiEdit = new MultiTextEdit(regionStartOffset, regionLength);
      RewriteSessionEditProcessor processor =
          new RewriteSessionEditProcessor(
              document, multiEdit, TextEdit.UPDATE_REGIONS | TextEdit.CREATE_UNDO);
      for (int i = nofLines; i >= 0; i--) {
        lineLength = document.getLineLength(startLine + i);
        offset = document.getLineOffset(startLine + i);
        realOffset = getRealLineStart(document, offset, lineLength);
        interval = rootInterval.getSmallestEnclosingInterval(realOffset);
        int indentLevel = lineIndentationLevel(document, realOffset, offset + lineLength, interval);
        setIndentLevel(document, document.getLineOffset(startLine + i), indentLevel);
      }

      performEdits(processor);

    } catch (BadLocationException e) {
      ErrorReporter.logExceptionStackTrace(e);
    }
    return;
  }