/** {@inheritDoc} */
 @Override
 public LinearRange getSelection(final Document document) {
   if (region == null) {
     // keep cursor location
     return LinearRange.createWithStart(cursorOffset).andLength(0);
   } else {
     return LinearRange.createWithStart(region.getOffset()).andLength(region.getLength());
   }
 }
  private int collectQuickFixableAnnotations(
      final LinearRange lineRange,
      Document document,
      final Map<Annotation, Position> annotations,
      final boolean goToClosest,
      List<Problem> resultingProblems) {
    int invocationLocation = lineRange.getStartOffset();
    if (goToClosest) {

      LinearRange line =
          document.getLinearRangeForLine(
              document.getPositionFromIndex(lineRange.getStartOffset()).getLine());
      int rangeStart = line.getStartOffset();
      int rangeEnd = rangeStart + line.getLength();

      ArrayList<Position> allPositions = new ArrayList<>();
      List<JavaAnnotation> allAnnotations = new ArrayList<>();
      int bestOffset = Integer.MAX_VALUE;
      for (Annotation problem : annotations.keySet()) {
        if (problem instanceof JavaAnnotation) {
          JavaAnnotation ann = ((JavaAnnotation) problem);

          Position pos = annotations.get(problem);
          if (pos != null && isInside(pos.offset, rangeStart, rangeEnd)) { // inside our range?

            allAnnotations.add(ann);
            allPositions.add(pos);
            bestOffset = processAnnotation(problem, pos, invocationLocation, bestOffset);
          }
        }
      }
      if (bestOffset == Integer.MAX_VALUE) {
        return invocationLocation;
      }
      for (int i = 0; i < allPositions.size(); i++) {
        Position pos = allPositions.get(i);
        if (isInside(bestOffset, pos.offset, pos.offset + pos.length)) {
          resultingProblems.add(createProblem(allAnnotations.get(i), pos));
        }
      }
      return bestOffset;
    } else {
      for (Annotation problem : annotations.keySet()) {
        Position pos = annotations.get(problem);
        if (pos != null && isInside(invocationLocation, pos.offset, pos.offset + pos.length)) {
          resultingProblems.add(createProblem((JavaAnnotation) problem, pos));
        }
      }
      return invocationLocation;
    }
  }
  @Override
  public void computeQuickAssistProposals(
      final QuickAssistInvocationContext quickAssistContext, final CodeAssistCallback callback) {
    final TextEditor textEditor = quickAssistContext.getTextEditor();
    final Document document = textEditor.getDocument();

    LinearRange tempRange;

    tempRange = textEditor.getSelectedLinearRange();

    final LinearRange range = tempRange;

    final boolean goToClosest = (range.getLength() == 0);

    final QueryAnnotationsEvent.AnnotationFilter filter =
        new QueryAnnotationsEvent.AnnotationFilter() {
          @Override
          public boolean accept(final Annotation annotation) {
            if (!(annotation instanceof JavaAnnotation)) {
              return false;
            } else {
              JavaAnnotation javaAnnotation = (JavaAnnotation) annotation;
              return (!javaAnnotation
                  .isMarkedDeleted()) /*&& JavaAnnotationUtil.hasCorrections(annotation)*/;
            }
          }
        };
    final QueryAnnotationsEvent.QueryCallback queryCallback =
        new QueryAnnotationsEvent.QueryCallback() {
          @Override
          public void respond(final Map<Annotation, Position> annotations) {
            List<Problem> problems = new ArrayList<>();
            /*final Map<Annotation, Position> problems =*/
            int offset =
                collectQuickFixableAnnotations(range, document, annotations, goToClosest, problems);
            if (offset != range.getStartOffset()) {
              TextEditorPresenter presenter = ((TextEditorPresenter) textEditor);
              presenter.getCursorModel().setCursorPosition(offset);
            }

            setupProposals(callback, textEditor, offset, problems);
          }
        };
    final QueryAnnotationsEvent event =
        new QueryAnnotationsEvent.Builder().withFilter(filter).withCallback(queryCallback).build();
    document.getDocumentHandle().getDocEventBus().fireEvent(event);
  }