@NotNull
  public static Map<PsiElement, ExpressionTypeProvider> getExpressions(@NotNull PsiFile file,
                                                                        @NotNull TextRange range,
                                                                        @NotNull Document document,
                                                                        @NotNull Set<? extends ExpressionTypeProvider> handlers) {
    if (handlers.isEmpty()) return Collections.emptyMap();
    boolean exactRange = false;
    final Map<PsiElement, ExpressionTypeProvider> map = new LinkedHashMap<>();
    int offset = !range.isEmpty() ? range.getStartOffset() : TargetElementUtil.adjustOffset(file, document, range.getStartOffset());
    for (int i = 0; i < 3 && map.isEmpty() && offset >= i; i++) {
      PsiElement elementAt = file.findElementAt(offset - i);
      if (elementAt == null) continue;
      for (ExpressionTypeProvider handler : handlers) {
        for (PsiElement element : ((ExpressionTypeProvider<? extends PsiElement>)handler).getExpressionsAt(elementAt)) {
          TextRange r = element.getTextRange();
          if (exactRange && !r.equals(range) || !r.contains(range)) continue;
          if (!exactRange) exactRange = r.equals(range);
          map.put(element, handler);
        }
      }
    }
    return map;
  }
@NotNull
  public static Map<PsiElement, ExpressionTypeProvider> getExpressions(@NotNull PsiFile file,
                                                                        @NotNull TextRange range,
                                                                        @NotNull Document document,
                                                                        @NotNull Set<? extends ExpressionTypeProvider> handlers)