You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by db...@apache.org on 2022/05/06 08:10:42 UTC

[netbeans] branch master updated: LSP: Javadoc code completion added. (#4071)

This is an automated email from the ASF dual-hosted git repository.

dbalek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 5ddff5d755 LSP: Javadoc code completion added. (#4071)
5ddff5d755 is described below

commit 5ddff5d755ac922addb101cc5a9148fd6cb7d406
Author: Dusan Balek <du...@oracle.com>
AuthorDate: Fri May 6 10:10:36 2022 +0200

    LSP: Javadoc code completion added. (#4071)
---
 .../base/javadoc/JavadocCompletionUtils.java       |   54 +-
 .../editor/java/JavaCompletionCollector.java       |  343 +++--
 .../editor/javadoc/JavadocCompletionCollector.java |  294 +++++
 .../java/editor/javadoc/JavadocCompletionItem.java |  178 +--
 .../editor/javadoc/JavadocCompletionQuery.java     | 1345 +-------------------
 ...letionQuery.java => JavadocCompletionTask.java} |  938 ++++++--------
 .../modules/java/editor/javadoc/TagRegistery.java  |    8 +
 .../editor/javadoc/JavadocCompletionQueryTest.java |  239 +++-
 .../nbcode/nbproject/platform.properties           |    2 -
 .../modules/java/lsp/server/protocol/Server.java   |    2 +-
 java/javadoc/nbproject/project.xml                 |    9 +
 .../javadoc/hints/GenerateJavadocCollector.java    |  123 ++
 12 files changed, 1409 insertions(+), 2126 deletions(-)

diff --git a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/javadoc/JavadocCompletionUtils.java b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/javadoc/JavadocCompletionUtils.java
index 68cd055b19..a0682653d7 100644
--- a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/javadoc/JavadocCompletionUtils.java
+++ b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/javadoc/JavadocCompletionUtils.java
@@ -337,25 +337,63 @@ public final class JavadocCompletionUtils {
     }
     
     private static final Set<DocTree.Kind> BLOCK_TAGS =
-            EnumSet.of(DocTree.Kind.AUTHOR, DocTree.Kind.DEPRECATED, DocTree.Kind.PARAM,
+            EnumSet.of(DocTree.Kind.AUTHOR, DocTree.Kind.DEPRECATED, DocTree.Kind.EXCEPTION,
+                       DocTree.Kind.HIDDEN,DocTree.Kind.PARAM, DocTree.Kind.PROVIDES,
                        DocTree.Kind.RETURN, DocTree.Kind.SEE, DocTree.Kind.SERIAL,
-                       DocTree.Kind.SERIAL_DATA, DocTree.Kind.SERIAL_FIELD, DocTree.Kind.SINCE,
-                       DocTree.Kind.THROWS, DocTree.Kind.UNKNOWN_BLOCK_TAG, DocTree.Kind.VERSION);
+                       DocTree.Kind.SERIAL_DATA, DocTree.Kind.SERIAL_FIELD,
+                       DocTree.Kind.SINCE, DocTree.Kind.THROWS, DocTree.Kind.USES, DocTree.Kind.VERSION,
+                       DocTree.Kind.UNKNOWN_BLOCK_TAG);
     public static boolean isBlockTag(DocTreePath tag) {
         return BLOCK_TAGS.contains(normalizedKind(tag.getLeaf()));
     }
 
+    private static final Set<DocTree.Kind> INLINE_TAGS =
+            EnumSet.of(DocTree.Kind.CODE, DocTree.Kind.DOC_ROOT, DocTree.Kind.INDEX,
+                       DocTree.Kind.INHERIT_DOC, DocTree.Kind.LINK, DocTree.Kind.LINK_PLAIN,
+                       DocTree.Kind.LITERAL, DocTree.Kind.SNIPPET, DocTree.Kind.SUMMARY,
+                       DocTree.Kind.SYSTEM_PROPERTY, DocTree.Kind.VALUE, DocTree.Kind.UNKNOWN_INLINE_TAG);
+    public static boolean isInlineTag(DocTreePath tag) {
+        return INLINE_TAGS.contains(normalizedKind(tag.getLeaf()));
+    }
+
     public static DocTree.Kind normalizedKind(DocTree tag) {
         DocTree.Kind normalizedKind = tag.getKind();
         if (normalizedKind == com.sun.source.doctree.DocTree.Kind.ERRONEOUS) {
-            String errorBody = ((ErroneousTree) tag).getBody();
-            switch (errorBody.split("\\s")[0]) {
-                case "@throws": normalizedKind = DocTree.Kind.THROWS; break;
-                case "@see": normalizedKind = DocTree.Kind.SEE; break;
+            String txt = ((ErroneousTree) tag).getBody().split("\\s")[0];
+            switch (txt) {
+                case "@author": normalizedKind = DocTree.Kind.AUTHOR; break;
+                case "@deprecated": normalizedKind = DocTree.Kind.DEPRECATED; break;
+                case "@exception": normalizedKind = DocTree.Kind.EXCEPTION; break;
+                case "@hidden": normalizedKind = DocTree.Kind.HIDDEN; break;
                 case "@param": normalizedKind = DocTree.Kind.PARAM; break;
-                case "{@value": normalizedKind = DocTree.Kind.VALUE; break;
+                case "@provides": normalizedKind = DocTree.Kind.PROVIDES; break;
+                case "@return": normalizedKind = DocTree.Kind.RETURN; break;
+                case "@see": normalizedKind = DocTree.Kind.SEE; break;
+                case "@serial": normalizedKind = DocTree.Kind.SERIAL; break;
+                case "@serialData": normalizedKind = DocTree.Kind.SERIAL_DATA; break;
+                case "@serialField": normalizedKind = DocTree.Kind.SERIAL_FIELD; break;
+                case "@since": normalizedKind = DocTree.Kind.SINCE; break;
+                case "@throws": normalizedKind = DocTree.Kind.THROWS; break;
+                case "@uses": normalizedKind = DocTree.Kind.USES; break;
+                case "@version": normalizedKind = DocTree.Kind.VERSION; break;
+                case "{@code": normalizedKind = DocTree.Kind.CODE; break;
+                case "{@docRoot": normalizedKind = DocTree.Kind.DOC_ROOT; break;
+                case "{@index": normalizedKind = DocTree.Kind.INDEX; break;
+                case "{@inheritDoc": normalizedKind = DocTree.Kind.INHERIT_DOC; break;
                 case "{@link": normalizedKind = DocTree.Kind.LINK; break;
                 case "{@linkplain": normalizedKind = DocTree.Kind.LINK; break;
+                case "{@literal": normalizedKind = DocTree.Kind.LITERAL; break;
+                case "{@snippet": normalizedKind = DocTree.Kind.SNIPPET; break;
+                case "{@summary": normalizedKind = DocTree.Kind.SUMMARY; break;
+                case "{@systemProperty": normalizedKind = DocTree.Kind.SYSTEM_PROPERTY; break;
+                case "{@value": normalizedKind = DocTree.Kind.VALUE; break;
+                default:
+                    if (txt.startsWith("@")) {
+                        normalizedKind = DocTree.Kind.UNKNOWN_BLOCK_TAG;
+                    } else if (txt.startsWith("{@")) {
+                        normalizedKind = DocTree.Kind.UNKNOWN_INLINE_TAG;
+                    }
+                    break;
             }
         }
         return normalizedKind;
diff --git a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
index ca35d46d7f..0418229640 100644
--- a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
+++ b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
@@ -110,57 +110,179 @@ public class JavaCompletionCollector implements CompletionCollector {
     @Override
     public boolean collectCompletions(Document doc, int offset, Completion.Context context, Consumer<Completion> consumer) {
         AtomicBoolean ret = new AtomicBoolean(true);
-        try {
-            ParserManager.parse(Collections.singletonList(Source.create(doc)), new UserTask() {
-                @Override
-                public void run(ResultIterator resultIterator) throws Exception {
-                    TokenSequence<JavaTokenId> ts = null;
-                    for (TokenSequence<?> cand : resultIterator.getSnapshot().getTokenHierarchy().embeddedTokenSequences(offset, false)) {
-                        if (cand.language() == JavaTokenId.language()) {
-                            ts = (TokenSequence<JavaTokenId>) cand;
-                            break;
-                        }
-                    }
-                    if (ts == null) {//No Java on this offset
-                        return ;
-                    }
-                    if (ts.move(offset) == 0 || !ts.moveNext()) {
-                        if (!ts.movePrevious()) {
-                            ts.moveNext();
+        if ((context == null || context.getTriggerKind() != Completion.TriggerKind.TriggerCharacter || context.getTriggerCharacter() == '.')
+                && Utilities.isJavaContext(doc, offset, true)) {
+            try {
+                ParserManager.parse(Collections.singletonList(Source.create(doc)), new UserTask() {
+                    @Override
+                    public void run(ResultIterator resultIterator) throws Exception {
+                        TokenSequence<JavaTokenId> ts = SourceUtils.getJavaTokenSequence(resultIterator.getSnapshot().getTokenHierarchy(), offset);
+                        if (ts.move(offset) == 0 || !ts.moveNext()) {
+                            if (!ts.movePrevious()) {
+                                ts.moveNext();
+                            }
                         }
-                    }
-                    int len = offset - ts.offset();
-                    boolean combinedCompletion = context != null && context.getTriggerKind() == Completion.TriggerKind.TriggerForIncompleteCompletions
-                            || len > 0 && ts.token().length() >= len && ts.token().id() == JavaTokenId.IDENTIFIER;
-                    CompilationController controller = CompilationController.get(resultIterator.getParserResult(ts.offset()));
-                    controller.toPhase(JavaSource.Phase.RESOLVED);
-                    JavaCompletionTask<Completion> task = JavaCompletionTask.create(offset, new ItemFactoryImpl(controller, offset), combinedCompletion ? EnumSet.of(JavaCompletionTask.Options.COMBINED_COMPLETION) : EnumSet.noneOf(JavaCompletionTask.Options.class), () -> false);
-                    task.run(resultIterator);
-                    List<Completion> results = task.getResults();
-                    if (results != null) {
-                        for (Iterator<Completion> it = results.iterator(); it.hasNext();) {
-                            Completion item = it.next();
-                            if (item == null) {
-                                it.remove();
+                        int len = offset - ts.offset();
+                        boolean combinedCompletion = context != null && context.getTriggerKind() == Completion.TriggerKind.TriggerForIncompleteCompletions
+                                || len > 0 && ts.token().length() >= len && ts.token().id() == JavaTokenId.IDENTIFIER;
+                        CompilationController controller = CompilationController.get(resultIterator.getParserResult(ts.offset()));
+                        controller.toPhase(JavaSource.Phase.RESOLVED);
+                        JavaCompletionTask<Completion> task = JavaCompletionTask.create(offset, new ItemFactoryImpl(controller, offset), combinedCompletion ? EnumSet.of(JavaCompletionTask.Options.COMBINED_COMPLETION) : EnumSet.noneOf(JavaCompletionTask.Options.class), () -> false);
+                        task.run(resultIterator);
+                        List<Completion> results = task.getResults();
+                        if (results != null) {
+                            for (Iterator<Completion> it = results.iterator(); it.hasNext();) {
+                                Completion item = it.next();
+                                if (item == null) {
+                                    it.remove();
+                                }
                             }
+                            results.forEach(consumer);
+                        }
+                        if (task.hasAdditionalClasses() || task.hasAdditionalMembers()) {
+                            ret.set(false);
                         }
-                        results.forEach(consumer);
-                    }
-                    if (task.hasAdditionalClasses() || task.hasAdditionalMembers()) {
-                        ret.set(false);
                     }
-                }
-            });
-        } catch (ParseException ex) {
-            Exceptions.printStackTrace(ex);
+                });
+            } catch (ParseException ex) {
+                Exceptions.printStackTrace(ex);
+            }
         }
         return ret.get();
     }
 
+    public static final Set<String> SUPPORTED_ELEMENT_KINDS = new HashSet<>(Arrays.asList("PACKAGE", "CLASS", "INTERFACE", "ENUM", "ANNOTATION_TYPE", "METHOD", "CONSTRUCTOR", "INSTANCE_INIT", "STATIC_INIT", "FIELD", "ENUM_CONSTANT", "TYPE_PARAMETER", "MODULE"));
+
+    public static Supplier<String> getDocumentation(Document doc, int offset, ElementHandle handle) {
+        return () -> {
+            try {
+                JavaDocumentationTask<Future<String>> task = JavaDocumentationTask.create(offset, handle, new JavaDocumentationTask.DocumentationFactory<Future<String>>() {
+                    @Override
+                    public Future<String> create(CompilationInfo compilationInfo, Element element, Callable<Boolean> cancel) {
+                        return ElementJavadoc.create(compilationInfo, element, cancel).getTextAsync();
+                    }
+                }, () -> false);
+                ParserManager.parse(Collections.singletonList(Source.create(doc)), new UserTask() {
+                    @Override
+                    public void run(ResultIterator resultIterator) throws Exception {
+                        task.run(resultIterator);
+                    }
+                });
+                return task.getDocumentation().get();
+            } catch (Exception ex) {
+                throw new RuntimeException(ex);
+            }
+        };
+    }
+
+    public static Completion.Kind elementKind2CompletionItemKind(ElementKind kind) {
+        switch (kind) {
+            case PACKAGE:
+                return Completion.Kind.Folder;
+            case ENUM:
+                return Completion.Kind.Enum;
+            case CLASS:
+                return Completion.Kind.Class;
+            case ANNOTATION_TYPE:
+                return Completion.Kind.Interface;
+            case INTERFACE:
+                return Completion.Kind.Interface;
+            case ENUM_CONSTANT:
+                return Completion.Kind.EnumMember;
+            case FIELD:
+                return Completion.Kind.Field;
+            case PARAMETER:
+                return Completion.Kind.Variable;
+            case LOCAL_VARIABLE:
+                return Completion.Kind.Variable;
+            case EXCEPTION_PARAMETER:
+                return Completion.Kind.Variable;
+            case METHOD:
+                return Completion.Kind.Method;
+            case CONSTRUCTOR:
+                return Completion.Kind.Constructor;
+            case TYPE_PARAMETER:
+                return Completion.Kind.TypeParameter;
+            case RESOURCE_VARIABLE:
+                return Completion.Kind.Variable;
+            case MODULE:
+                return Completion.Kind.Module;
+            case STATIC_INIT:
+            case INSTANCE_INIT:
+            case OTHER:
+            default:
+                return Completion.Kind.Text;
+        }
+    }
+
+    public static Supplier<List<TextEdit>> addImport(Document doc, ElementHandle<?> handle) {
+        return () -> {
+            try {
+                TextEdit textEdit = modify2TextEdit(JavaSource.forDocument(doc), copy -> {
+                    copy.toPhase(JavaSource.Phase.RESOLVED);
+                    Element e = handle.resolve(copy);
+                    if (e != null) {
+                        copy.rewrite(copy.getCompilationUnit(), GeneratorUtilities.get(copy).addImports(copy.getCompilationUnit(), Collections.singleton(e)));
+                    }
+                });
+                return textEdit != null ? Collections.singletonList(textEdit) : null;
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        };
+    }
+
+    public static boolean isOfKind(Element e, EnumSet<ElementKind> kinds) {
+        if (kinds.contains(e.getKind())) {
+            return true;
+        }
+        for (Element ee : e.getEnclosedElements()) {
+            if (isOfKind(ee, kinds)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean isInDefaultPackage(Element e) {
+        while (e != null && e.getKind() != ElementKind.PACKAGE) {
+            e = e.getEnclosingElement();
+        }
+        return e != null && e.getSimpleName().length() == 0;
+    }
+
+    private static TextEdit modify2TextEdit(JavaSource js, Task<WorkingCopy> task) throws IOException {
+        FileObject[] file = new FileObject[1];
+        ModificationResult changes = js.runModificationTask(wc -> {
+            task.run(wc);
+            file[0] = wc.getFileObject();
+        });
+        List<? extends ModificationResult.Difference> diffs = changes.getDifferences(file[0]);
+        if (diffs == null) {
+            return null;
+        }
+        int startOffset = -1;
+        int endOffset = -1;
+        StringBuilder sb = new StringBuilder();
+        for (ModificationResult.Difference diff : diffs) {
+            int start = diff.getStartPosition().getOffset();
+            int end = diff.getEndPosition().getOffset();
+            String newText = diff.getNewText();
+            if (startOffset < 0 && endOffset < 0) {
+                startOffset = start;
+                endOffset = end;
+                sb.append(newText);
+            } else if (start == endOffset) {
+                endOffset = end;
+                sb.append(newText);
+            }
+        }
+        return startOffset >= 0 && endOffset >= startOffset ? new TextEdit(startOffset, endOffset, sb.toString()) : null;
+    }
+
     private static class ItemFactoryImpl implements JavaCompletionTask.TypeCastableItemFactory<Completion>,
             JavaCompletionTask.LambdaItemFactory<Completion>, JavaCompletionTask.ModuleItemFactory<Completion> {
 
-        private static final Set<String> SUPPORTED_ELEMENT_KINDS = new HashSet<>(Arrays.asList("PACKAGE", "CLASS", "INTERFACE", "ENUM", "ANNOTATION_TYPE", "METHOD", "CONSTRUCTOR", "INSTANCE_INIT", "STATIC_INIT", "FIELD", "ENUM_CONSTANT", "TYPE_PARAMETER", "MODULE"));
         private static final String EMPTY = "";
         private static final String ERROR = "<error>";
         private static final int DEPRECATED = 10;
@@ -264,7 +386,7 @@ public class JavaCompletionCollector implements CompletionCollector {
                         .detail(label.insert(0, elem.getQualifiedName()).toString());
                 ElementHandle<TypeElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
                 if (handle != null) {
-                    builder.documentation(getDocumentation(doc, handle));
+                    builder.documentation(getDocumentation(doc, offset, handle));
                 }
                 if (elements.isDeprecated(elem)) {
                     builder.addTag(Completion.Tag.Deprecated);
@@ -333,7 +455,7 @@ public class JavaCompletionCollector implements CompletionCollector {
             }
             ElementHandle<VariableElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
             if (handle != null) {
-                builder.documentation(getDocumentation(doc, handle));
+                builder.documentation(getDocumentation(doc, offset, handle));
             }
             if (isDeprecated) {
                 builder.addTag(Completion.Tag.Deprecated);
@@ -374,7 +496,7 @@ public class JavaCompletionCollector implements CompletionCollector {
                     .insertTextFormat(Completion.TextFormat.PlainText);
             ElementHandle<ExecutableElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
             if (handle != null) {
-                builder.documentation(getDocumentation(doc, handle));
+                builder.documentation(getDocumentation(doc, offset, handle));
             }
             try {
                 TextEdit textEdit = modify2TextEdit(JavaSource.forFileObject(info.getFileObject()), wc -> {
@@ -519,7 +641,7 @@ public class JavaCompletionCollector implements CompletionCollector {
                     .sortText(String.format("%04d%s", isDeprecated ? 100 + DEPRECATED : 100, elem.getSimpleName().toString()));
             ElementHandle<ExecutableElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
             if (handle != null) {
-                builder.documentation(getDocumentation(doc, handle));
+                builder.documentation(getDocumentation(doc, offset, handle));
             }
             if (isDeprecated) {
                 builder.addTag(Completion.Tag.Deprecated);
@@ -621,7 +743,7 @@ public class JavaCompletionCollector implements CompletionCollector {
             }
             ElementHandle<Element> handle = SUPPORTED_ELEMENT_KINDS.contains(memberElem.getKind().name()) ? ElementHandle.create(memberElem) : null;
             if (handle != null) {
-                builder.documentation(getDocumentation(doc, handle));
+                builder.documentation(getDocumentation(doc, offset, handle));
             }
             if (isDeprecated) {
                 builder.addTag(Completion.Tag.Deprecated);
@@ -885,7 +1007,7 @@ public class JavaCompletionCollector implements CompletionCollector {
                             .addCommitCharacter('.');
             }
             if (handle != null) {
-                builder.documentation(getDocumentation(doc, handle));
+                builder.documentation(getDocumentation(doc, offset, handle));
                 if (!addSimpleName && !inImport) {
                     builder.additionalTextEdits(addImport(doc, handle));
                 }
@@ -1001,7 +1123,7 @@ public class JavaCompletionCollector implements CompletionCollector {
 
             ElementHandle<ExecutableElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
             if (handle != null) {
-                builder.documentation(getDocumentation(doc, handle));
+                builder.documentation(getDocumentation(doc, offset, handle));
             }
             if (isDeprecated) {
                 builder.addTag(Completion.Tag.Deprecated);
@@ -1092,28 +1214,6 @@ public class JavaCompletionCollector implements CompletionCollector {
             return locals;
         }
 
-        private Supplier<String> getDocumentation(Document doc, ElementHandle handle) {
-            return () -> {
-                try {
-                    JavaDocumentationTask<Future<String>> task = JavaDocumentationTask.create(offset, handle, new JavaDocumentationTask.DocumentationFactory<Future<String>>() {
-                        @Override
-                        public Future<String> create(CompilationInfo compilationInfo, Element element, Callable<Boolean> cancel) {
-                            return ElementJavadoc.create(compilationInfo, element, cancel).getTextAsync();
-                        }
-                    }, () -> false);
-                    ParserManager.parse(Collections.singletonList(Source.create(doc)), new UserTask() {
-                        @Override
-                        public void run(ResultIterator resultIterator) throws Exception {
-                            task.run(resultIterator);
-                        }
-                    });
-                    return task.getDocumentation().get();
-                } catch (Exception ex) {
-                    throw new RuntimeException(ex);
-                }
-            };
-        }
-
         private static boolean isSameType(TypeMirror t1, TypeMirror t2, Types types) {
             if (types.isSameType(t1, t2)) {
                 return true;
@@ -1124,25 +1224,6 @@ public class JavaCompletionCollector implements CompletionCollector {
             return t2.getKind().isPrimitive() && types.isSameType(t1, types.boxedClass((PrimitiveType)t2).asType());
         }
 
-        private static boolean isOfKind(Element e, EnumSet<ElementKind> kinds) {
-            if (kinds.contains(e.getKind())) {
-                return true;
-            }
-            for (Element ee : e.getEnclosedElements()) {
-                if (isOfKind(ee, kinds)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        private static boolean isInDefaultPackage(Element e) {
-            while (e != null && e.getKind() != ElementKind.PACKAGE) {
-                e = e.getEnclosingElement();
-            }
-            return e != null && e.getSimpleName().length() == 0;
-        }
-
         private static boolean allowDiamond(CompilationInfo info, int offset, DeclaredType type) {
             TreeUtilities tu = info.getTreeUtilities();
             TreePath path = tu.pathFor(offset);
@@ -1174,23 +1255,6 @@ public class JavaCompletionCollector implements CompletionCollector {
             return false;
         }
 
-        private static Supplier<List<TextEdit>> addImport(Document doc, ElementHandle<?> handle) {
-            return () -> {
-                try {
-                    TextEdit textEdit = modify2TextEdit(JavaSource.forDocument(doc), copy -> {
-                        copy.toPhase(JavaSource.Phase.RESOLVED);
-                        Element e = handle.resolve(copy);
-                        if (e != null) {
-                            copy.rewrite(copy.getCompilationUnit(), GeneratorUtilities.get(copy).addImports(copy.getCompilationUnit(), Collections.singleton(e)));
-                        }
-                    });
-                    return textEdit != null ? Collections.singletonList(textEdit) : null;
-                } catch (IOException ex) {
-                    throw new RuntimeException(ex);
-                }
-            };
-        }
-
         private static int findCastEndPosition(TokenSequence<JavaTokenId> ts, int startPos, int endPos) {
             TokenSequence<JavaTokenId> last = findLastNonWhitespaceToken(ts, startPos, endPos);
             if (last != null && last.token().id() == JavaTokenId.DOT) {
@@ -1221,74 +1285,5 @@ public class JavaCompletionCollector implements CompletionCollector {
             }
             return null;
         }
-
-        private static Completion.Kind elementKind2CompletionItemKind(ElementKind kind) {
-            switch (kind) {
-                case PACKAGE:
-                    return Completion.Kind.Folder;
-                case ENUM:
-                    return Completion.Kind.Enum;
-                case CLASS:
-                    return Completion.Kind.Class;
-                case ANNOTATION_TYPE:
-                    return Completion.Kind.Interface;
-                case INTERFACE:
-                    return Completion.Kind.Interface;
-                case ENUM_CONSTANT:
-                    return Completion.Kind.EnumMember;
-                case FIELD:
-                    return Completion.Kind.Field;
-                case PARAMETER:
-                    return Completion.Kind.Variable;
-                case LOCAL_VARIABLE:
-                    return Completion.Kind.Variable;
-                case EXCEPTION_PARAMETER:
-                    return Completion.Kind.Variable;
-                case METHOD:
-                    return Completion.Kind.Method;
-                case CONSTRUCTOR:
-                    return Completion.Kind.Constructor;
-                case TYPE_PARAMETER:
-                    return Completion.Kind.TypeParameter;
-                case RESOURCE_VARIABLE:
-                    return Completion.Kind.Variable;
-                case MODULE:
-                    return Completion.Kind.Module;
-                case STATIC_INIT:
-                case INSTANCE_INIT:
-                case OTHER:
-                default:
-                    return Completion.Kind.Text;
-            }
-        }
-
-        private static TextEdit modify2TextEdit(JavaSource js, Task<WorkingCopy> task) throws IOException {
-            FileObject[] file = new FileObject[1];
-            ModificationResult changes = js.runModificationTask(wc -> {
-                task.run(wc);
-                file[0] = wc.getFileObject();
-            });
-            List<? extends ModificationResult.Difference> diffs = changes.getDifferences(file[0]);
-            if (diffs == null) {
-                return null;
-            }
-            int startOffset = -1;
-            int endOffset = -1;
-            StringBuilder sb = new StringBuilder();
-            for (ModificationResult.Difference diff : diffs) {
-                int start = diff.getStartPosition().getOffset();
-                int end = diff.getEndPosition().getOffset();
-                String newText = diff.getNewText();
-                if (startOffset < 0 && endOffset < 0) {
-                    startOffset = start;
-                    endOffset = end;
-                    sb.append(newText);
-                } else if (start == endOffset) {
-                    endOffset = end;
-                    sb.append(newText);
-                }
-            }
-            return startOffset >= 0 && endOffset >= startOffset ? new TextEdit(startOffset, endOffset, sb.toString()) : null;
-        }
     }
 }
diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionCollector.java b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionCollector.java
new file mode 100644
index 0000000000..177e5c4a0b
--- /dev/null
+++ b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionCollector.java
@@ -0,0 +1,294 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.editor.javadoc;
+
+import com.sun.source.tree.Scope;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.swing.text.Document;
+import org.netbeans.api.editor.mimelookup.MimeRegistration;
+import org.netbeans.api.java.source.CompilationController;
+import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.support.ReferencesCount;
+import org.netbeans.api.lsp.Completion;
+import org.netbeans.api.lsp.TextEdit;
+import org.netbeans.modules.editor.java.JavaCompletionCollector;
+import org.netbeans.modules.editor.java.Utilities;
+import org.netbeans.modules.java.editor.base.javadoc.JavadocCompletionUtils;
+import org.netbeans.modules.parsing.api.ParserManager;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.ParseException;
+import org.netbeans.spi.lsp.CompletionCollector;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author Dusan Balek
+ */
+@MimeRegistration(mimeType = "text/x-java", service = CompletionCollector.class)
+public class JavadocCompletionCollector implements CompletionCollector {
+
+    @Override
+    public boolean collectCompletions(Document doc, int offset, Completion.Context context, Consumer<Completion> consumer) {
+        AtomicBoolean ret = new AtomicBoolean(true);
+        if ((context == null || context.getTriggerKind() != Completion.TriggerKind.TriggerCharacter || context.getTriggerCharacter() == '#' || context.getTriggerCharacter() == '@')
+                && JavadocCompletionUtils.isJavadocContext(doc, offset)) {
+            try {
+                ParserManager.parse(Collections.singletonList(Source.create(doc)), new UserTask() {
+                    @Override
+                    public void run(ResultIterator resultIterator) throws Exception {
+                        CompilationController controller = CompilationController.get(resultIterator.getParserResult(offset));
+                        controller.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
+                        JavadocCompletionTask<Completion> task = JavadocCompletionTask.create(offset, new ItemFactoryImpl(controller, offset),
+                                context != null && context.getTriggerKind() == Completion.TriggerKind.TriggerForIncompleteCompletions, () -> false);
+                        task.run(resultIterator);
+                        List<Completion> results = task.getResults();
+                        if (results != null) {
+                            for (Iterator<Completion> it = results.iterator(); it.hasNext();) {
+                                Completion item = it.next();
+                                if (item == null) {
+                                    it.remove();
+                                }
+                            }
+                            results.forEach(consumer);
+                        }
+                        if (task.hasAdditionalItems()) {
+                            ret.set(false);
+                        }
+                    }
+                });
+            } catch (ParseException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        }
+        return ret.get();
+    }
+
+    private static class ItemFactoryImpl implements JavadocCompletionTask.ItemFactory<Completion> {
+
+        private final CompilationInfo info;
+        private final Document doc;
+        private final int offset;
+        private final Scope scope;
+
+        public ItemFactoryImpl(CompilationInfo info, int offset) throws IOException {
+            this.info = info;
+            this.doc = info.getDocument();
+            this.offset = offset;
+            this.scope = getScope();
+        }
+
+        @Override
+        public Completion createTagItem(String name, int startOffset) {
+            Builder builder = CompletionCollector.newBuilder(name)
+                    .kind(Completion.Kind.Keyword)
+                    .sortText(String.format("%04d%s", 1500, name))
+                    .insertTextFormat(Completion.TextFormat.PlainText);
+            if (startOffset < offset) {
+                builder.textEdit(new TextEdit(startOffset, offset, name + ' '));
+            } else {
+                builder.insertText(name + ' ');
+            }
+            return builder.build();
+        }
+
+        @Override
+        public Completion createNameItem(String name, int startOffset) {
+            return CompletionCollector.newBuilder(name)
+                    .kind(name.charAt(0) == '<' ? Completion.Kind.TypeParameter : Completion.Kind.Variable)
+                    .insertText(name + ' ')
+                    .sortText(String.format("%04d%s", 1100, name))
+                    .insertTextFormat(Completion.TextFormat.PlainText)
+                    .build();
+        }
+
+        @Override
+        public Completion createJavadocExecutableItem(CompilationInfo info, ExecutableElement elem, ExecutableType type, int startOffset, boolean isInherited, boolean isDeprecated) {
+            String simpleName = (elem.getKind() == ElementKind.METHOD ? elem : elem.getEnclosingElement()).getSimpleName().toString();
+            Iterator<? extends VariableElement> it = elem.getParameters().iterator();
+            Iterator<? extends TypeMirror> tIt = type.getParameterTypes().iterator();
+            StringBuilder label = new StringBuilder();
+            StringBuilder insertText = new StringBuilder();
+            StringBuilder sortParams = new StringBuilder();
+            label.append(simpleName).append('(');
+            insertText.append(simpleName).append('(');
+            sortParams.append('(');
+            int cnt = 0;
+            while(it.hasNext() && tIt.hasNext()) {
+                TypeMirror tm = tIt.next();
+                if (tm == null) {
+                    break;
+                }
+                cnt++;
+                String paramTypeName = Utilities.getTypeName(info, tm, false, elem.isVarArgs() && !tIt.hasNext()).toString();
+                String paramName = it.next().getSimpleName().toString();
+                label.append(paramTypeName).append(' ').append(paramName);
+                sortParams.append(paramTypeName);
+                insertText.append(paramTypeName);
+                if (tIt.hasNext()) {
+                    label.append(", ");
+                    sortParams.append(',');
+                    insertText.append(", ");
+                }
+            }
+            sortParams.append(')');
+            label.append(')');
+            insertText.append(')');
+            TypeMirror retType = type.getReturnType();
+            if (elem.getKind() == ElementKind.METHOD) {
+                label.append(" : ").append(Utilities.getTypeName(info, retType, false).toString());
+            }
+            int priority = elem.getKind() == ElementKind.METHOD ? 1500 : 1650;
+            CompletionCollector.Builder builder = CompletionCollector.newBuilder(label.toString())
+                    .kind(JavaCompletionCollector.elementKind2CompletionItemKind(elem.getKind()))
+                    .insertTextFormat(Completion.TextFormat.PlainText)
+                    .sortText(String.format("%04d%s#%02d%s", priority, simpleName, cnt, sortParams.toString()))
+                    .insertText(insertText.toString());
+
+            ElementHandle<ExecutableElement> handle = JavaCompletionCollector.SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
+            if (handle != null) {
+                builder.documentation(JavaCompletionCollector.getDocumentation(doc, offset, handle));
+            }
+            if (isDeprecated) {
+                builder.addTag(Completion.Tag.Deprecated);
+            }
+            return builder.build();
+        }
+
+        @Override
+        public Completion createJavadocTypeItem(CompilationInfo info, TypeElement elem, int startOffset, boolean isDeprecated) {
+            ElementHandle<TypeElement> handle = JavaCompletionCollector.SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
+            return createTypeItem(handle, elem, (DeclaredType) elem.asType(), '#', null, isDeprecated, false);
+        }
+
+        @Override
+        public Completion createJavaTypeItem(CompilationInfo info, TypeElement elem, DeclaredType type, int startOffset, ReferencesCount referencesCount, boolean isDeprecated, boolean smartType) {
+            ElementHandle<TypeElement> handle = JavaCompletionCollector.SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
+            return createTypeItem(handle, elem, type, (char) -1, referencesCount, isDeprecated, false);
+        }
+
+        @Override
+        public Completion createLazyTypeItem(ElementHandle<TypeElement> handle, EnumSet<ElementKind> kinds, int startOffset, ReferencesCount referencesCount, Source source) {
+            TypeElement te = handle.resolve(info);
+            if (te != null && (scope == null || info.getTrees().isAccessible(scope, te)) && JavaCompletionCollector.isOfKind(te, kinds) && (!JavaCompletionCollector.isInDefaultPackage(te) || JavaCompletionCollector.isInDefaultPackage(scope.getEnclosingClass()))) {
+                return createTypeItem(handle, te, (DeclaredType) te.asType(), (char) -1, referencesCount, info.getElements().isDeprecated(te), false);
+            }
+            return null;
+        }
+
+        @Override
+        public Completion createJavaVariableItem(CompilationInfo info, VariableElement elem, TypeMirror type, int startOffset, boolean isInherited, boolean isDeprecated) {
+            int priority = elem.getKind() == ElementKind.ENUM_CONSTANT || elem.getKind() == ElementKind.FIELD ? 1300 : 1200;
+            StringBuilder label = new StringBuilder();
+            label.append(elem.getSimpleName());
+            if (type != null) {
+                label.append(" : ").append(Utilities.getTypeName(info, type, false));
+            }
+            CompletionCollector.Builder builder = CompletionCollector.newBuilder(label.toString())
+                    .kind(JavaCompletionCollector.elementKind2CompletionItemKind(elem.getKind()))
+                    .sortText(String.format("%04d%s", priority, elem.getSimpleName().toString()))
+                    .insertTextFormat(Completion.TextFormat.PlainText)
+                    .insertText(elem.getSimpleName().toString());
+            if (type != null && !type.getKind().isPrimitive()) {
+                builder.addCommitCharacter('.');
+            }
+            ElementHandle<VariableElement> handle = JavaCompletionCollector.SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null;
+            if (handle != null) {
+                builder.documentation(JavaCompletionCollector.getDocumentation(doc, offset, handle));
+            }
+            if (isDeprecated) {
+                builder.addTag(Completion.Tag.Deprecated);
+            }
+            return builder.build();
+        }
+
+        @Override
+        public Completion createPackageItem(String pkgFQN, int startOffset) {
+            final String simpleName = pkgFQN.substring(pkgFQN.lastIndexOf('.') + 1);
+            return CompletionCollector.newBuilder(simpleName)
+                    .kind(Completion.Kind.Folder)
+                    .sortText(String.format("%04d%s#%s", 1900, simpleName, pkgFQN))
+                    .insertText(simpleName + '.')
+                    .insertTextFormat(Completion.TextFormat.PlainText)
+                    .build();
+        }
+
+        private Completion createTypeItem(ElementHandle<TypeElement> handle, TypeElement elem, DeclaredType type, char commitChar, ReferencesCount referencesCount, boolean isDeprecated, boolean smartType) {
+            String name = elem.getQualifiedName().toString();
+            int idx = name.lastIndexOf('.');
+            String pkgName = idx < 0 ? "" : name.substring(0, idx);
+            StringBuilder label = new StringBuilder();
+            StringBuilder insertText = new StringBuilder();
+            label.append(elem.getSimpleName());
+            if (pkgName.length() > 0) {
+                label.append(" (").append(pkgName).append(')');
+            }
+            if (referencesCount == null) {
+                insertText.append(elem.getSimpleName());
+            } else {
+                if ((type == null || type.getKind() != TypeKind.ERROR) &&
+                        EnumSet.range(ElementKind.PACKAGE, ElementKind.INTERFACE).contains(elem.getEnclosingElement().getKind())) {
+                    insertText.append(elem.getSimpleName());
+                } else {
+                    insertText.append(elem.getQualifiedName());
+                }
+            }
+            CompletionCollector.Builder builder = CompletionCollector.newBuilder(label.toString())
+                    .kind(JavaCompletionCollector.elementKind2CompletionItemKind(elem.getKind()))
+                    .sortText(String.format("%04d%s#%02d#%s", smartType ? 800 : 1800, elem.getSimpleName().toString(), Utilities.getImportanceLevel(name), pkgName))
+                    .insertText(insertText.toString())
+                    .insertTextFormat(Completion.TextFormat.PlainText);
+            if (commitChar != -1) {
+                builder.addCommitCharacter('#');
+            }
+            if (handle != null) {
+                builder.documentation(JavaCompletionCollector.getDocumentation(doc, offset, handle));
+                builder.additionalTextEdits(JavaCompletionCollector.addImport(doc, handle));
+            }
+            if (isDeprecated) {
+                builder.addTag(Completion.Tag.Deprecated);
+            }
+            return builder.build();
+        }
+
+        private Scope getScope() {
+            try {
+                return info.getTrees().getScope(info.getTreeUtilities().pathFor(offset));
+            } catch (Exception e) {}
+            return null;
+        }
+    }
+}
diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionItem.java b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionItem.java
index 83bf3450c7..2215192787 100644
--- a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionItem.java
+++ b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionItem.java
@@ -23,7 +23,7 @@ import java.awt.Color;
 import java.awt.Font;
 import java.awt.Graphics;
 import java.awt.event.KeyEvent;
-import java.util.ArrayList;
+import java.util.EnumSet;
 import java.util.List;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
@@ -43,10 +43,12 @@ import javax.swing.text.JTextComponent;
 import javax.swing.text.StyledDocument;
 import org.netbeans.api.editor.completion.Completion;
 import org.netbeans.api.java.source.CompilationInfo;
+import org.netbeans.api.java.source.ElementHandle;
 import org.netbeans.api.java.source.support.ReferencesCount;
 import org.netbeans.modules.editor.java.JavaCompletionItem;
+import org.netbeans.modules.editor.java.LazyJavaCompletionItem;
 import org.netbeans.modules.editor.java.Utilities;
-import org.netbeans.modules.java.editor.javadoc.TagRegistery.TagEntry;
+import org.netbeans.modules.parsing.api.Source;
 import org.netbeans.spi.editor.completion.CompletionItem;
 import org.netbeans.spi.editor.completion.CompletionTask;
 import org.netbeans.spi.editor.completion.support.CompletionUtilities;
@@ -69,10 +71,10 @@ final class JavadocCompletionItem implements CompletionItem {
     private static final String BOLD = "<b>"; //NOI18N
     private static final String BOLD_END = "</b>"; //NOI18N
     
-    private int substitutionOffset;
-    private String txt;
-    private String leftHtmlText;
-    private String rightHtmlText;
+    private final int substitutionOffset;
+    private final String txt;
+    private final String leftHtmlText;
+    private final String rightHtmlText;
     private final String iconPath;
     private final int sortPriority;
     private ImageIcon icon = null;
@@ -89,26 +91,27 @@ final class JavadocCompletionItem implements CompletionItem {
         this.sortPriority = sortPriority;
     }
 
+    @Override
     public void defaultAction(JTextComponent component) {
         Completion.get().hideAll();
         complete(component, txt + ' ', substitutionOffset);
     }
 
+    @Override
     public void processKeyEvent(KeyEvent evt) {
     }
 
+    @Override
     public final int getPreferredWidth(Graphics g, Font defaultFont) {
-        return CompletionUtilities.getPreferredWidth(
-                getLeftHtmlText(), getRightHtmlText(), g, defaultFont);
+        return CompletionUtilities.getPreferredWidth(getLeftHtmlText(), getRightHtmlText(), g, defaultFont);
     }
 
-    public final void render(Graphics g, Font defaultFont, Color defaultColor,
-            Color backgroundColor, int width, int height, boolean selected) {
+    @Override
+    public final void render(Graphics g, Font defaultFont, Color defaultColor, Color backgroundColor, int width, int height, boolean selected) {
         if (icon == null) {
             icon = createIcon();
         }
-        CompletionUtilities.renderHtml(icon, getLeftHtmlText(), getRightHtmlText(),
-                g, defaultFont, defaultColor, width, height, selected);
+        CompletionUtilities.renderHtml(icon, getLeftHtmlText(), getRightHtmlText(), g, defaultFont, defaultColor, width, height, selected);
     }
     
     protected ImageIcon createIcon() {
@@ -116,36 +119,39 @@ final class JavadocCompletionItem implements CompletionItem {
     }
     
     protected String getLeftHtmlText() {
-        if (leftHtmlText == null) {
-            leftHtmlText = txt;
-        }
-        return leftHtmlText;
+        return leftHtmlText == null ? txt : leftHtmlText;
     }
     
     protected String getRightHtmlText() {
         return rightHtmlText;
     }
     
+    @Override
     public CompletionTask createDocumentationTask() {
         return null;
     }
 
+    @Override
     public CompletionTask createToolTipTask() {
         return null;
     }
 
+    @Override
     public boolean instantSubstitution(JTextComponent component) {
         return false;
     }
 
+    @Override
     public int getSortPriority() {
         return sortPriority;
     }
 
+    @Override
     public CharSequence getSortText() {
         return txt;
     }
 
+    @Override
     public CharSequence getInsertPrefix() {
         return txt;
     }
@@ -155,62 +161,6 @@ final class JavadocCompletionItem implements CompletionItem {
         return super.toString() + String.format("[txt:%1$s, substitutionOffset:%2$d]",
                 txt, substitutionOffset);
     }
-
-    public static List<CompletionItem> addBlockTagItems(ElementKind kind,
-            String prefix, int startOffset) {
-        
-        List<TagEntry> tags = TagRegistery.getDefault().getTags(kind, false);
-        List<CompletionItem> items = new ArrayList<CompletionItem>(tags.size());
-        for (TagEntry tagEntry : tags) {
-            if (tagEntry.name.startsWith(prefix)) {
-                items.add(new JavadocCompletionItem(tagEntry.name, startOffset,
-                        null, null, JAVADOC_TAG_ICON, 500));
-            }
-        }
-        return items;
-    }
-
-    public static List<CompletionItem> addInlineTagItems(ElementKind kind,
-            String prefix, int startOffset) {
-        
-        List<TagEntry> tags = TagRegistery.getDefault().getTags(kind, true);
-        List<CompletionItem> items = new ArrayList<CompletionItem>(tags.size());
-        for (TagEntry tagEntry : tags) {
-            if (tagEntry.name.startsWith(prefix)) {
-                items.add(new JavadocCompletionItem(tagEntry.name, startOffset,
-                        null, null, JAVADOC_TAG_ICON, 500));
-            }
-        }
-        return items;
-    }
-    
-    public static CompletionItem createNameItem(String name, int startOffset) {
-        // escape type variable name
-        String html = name.charAt(0) == '<'
-                ? "&lt;" + name.substring(1, name.length() - 1) + "&gt;" // NOI18N
-                : name;
-        return new JavadocCompletionItem(name, startOffset,
-                PARAMETER_COLOR + BOLD + html + BOLD_END + COLOR_END,
-                null, JAVADOC_PARAM_ICON, 100);
-    }
-    
-    public static CompletionItem createExecutableItem(CompilationInfo info, ExecutableElement e,
-            ExecutableType et, int startOffset, boolean isInherited,
-            boolean isDeprecated) {
-        
-        CompletionItem delegate = JavaCompletionItem.createExecutableItem(
-                info, e, et, null, startOffset, null, isInherited, isDeprecated, false, false, false, -1, false, null);
-        return new JavadocExecutableItem(delegate, e, startOffset);
-    }
-    
-    public static CompletionItem createTypeItem(CompilationInfo info, TypeElement elem,
-            int startOffset, ReferencesCount referencesCount, boolean isDeprecated) {
-        
-        CompletionItem delegate = JavaCompletionItem.createTypeItem(
-                info, elem, (DeclaredType) elem.asType(), startOffset,
-                referencesCount, isDeprecated, false, false, false, false, false, null);
-        return new JavadocTypeItem(delegate, startOffset);
-    }
     
     private static void complete(final JTextComponent comp, final String what, final int where) {
         try {
@@ -241,6 +191,59 @@ final class JavadocCompletionItem implements CompletionItem {
         }
     }
     
+    public static final class Factory implements JavadocCompletionTask.ItemFactory<CompletionItem> {
+
+        @Override
+        public CompletionItem createTagItem(String name, int startOffset) {
+            return new JavadocCompletionItem(name, startOffset, null, null, JAVADOC_TAG_ICON, 500);
+        }
+
+        @Override
+        public CompletionItem createNameItem(String name, int startOffset) {
+            // escape type variable name
+            String html = name.charAt(0) == '<'
+                    ? "&lt;" + name.substring(1, name.length() - 1) + "&gt;" // NOI18N
+                    : name;
+            return new JavadocCompletionItem(name, startOffset,
+                    PARAMETER_COLOR + BOLD + html + BOLD_END + COLOR_END,
+                    null, JAVADOC_PARAM_ICON, 100);
+        }
+
+        @Override
+        public CompletionItem createJavadocExecutableItem(CompilationInfo info, ExecutableElement e, ExecutableType et, int startOffset, boolean isInherited, boolean isDeprecated) {
+            CompletionItem delegate = JavaCompletionItem.createExecutableItem(
+                    info, e, et, null, startOffset, null, isInherited, isDeprecated, false, false, false, -1, false, null);
+            return new JavadocExecutableItem(delegate, e, startOffset);
+        }
+
+        @Override
+        public CompletionItem createJavadocTypeItem(CompilationInfo info, TypeElement elem, int startOffset, boolean isDeprecated) {
+            CompletionItem delegate = JavaCompletionItem.createTypeItem(
+                    info, elem, (DeclaredType) elem.asType(), startOffset, null, isDeprecated, false, false, false, false, false, null);
+            return new JavadocTypeItem(delegate, startOffset);
+        }
+
+        @Override
+        public CompletionItem createJavaTypeItem(CompilationInfo info, TypeElement elem, DeclaredType type, int startOffset, ReferencesCount referencesCount, boolean isDeprecated, boolean smartType) {
+            return JavaCompletionItem.createTypeItem(info, elem, type, startOffset, referencesCount, isDeprecated, false, false, false, smartType, false, null);
+        }
+
+        @Override
+        public CompletionItem createLazyTypeItem(ElementHandle<TypeElement> handle, EnumSet<ElementKind> kinds, int startOffset, ReferencesCount referencesCount, Source source) {
+            return LazyJavaCompletionItem.createTypeItem(handle, kinds, startOffset, referencesCount, source, false, false, false, null);
+        }
+
+        @Override
+        public CompletionItem createJavaVariableItem(CompilationInfo info, VariableElement elem, TypeMirror type, int startOffset, boolean isInherited, boolean isDeprecated) {
+            return JavaCompletionItem.createVariableItem(info, elem, type, null, startOffset, null, isInherited, isDeprecated, false, -1, null);
+        }
+
+        @Override
+        public CompletionItem createPackageItem(String pkgFQN, int startOffset) {
+            return JavaCompletionItem.createPackageItem(pkgFQN, startOffset, false);
+        }
+    }
+
     /**
      * Reuses UI of {@code JavaCompletionItem.createExecutableItem} and
      * implements own text substitution.
@@ -298,6 +301,7 @@ final class JavadocCompletionItem implements CompletionItem {
             return ptype;
         }
 
+        @Override
         public void defaultAction(JTextComponent component) {
             if (component != null) {
                 Completion.get().hideDocumentation();
@@ -319,29 +323,32 @@ final class JavadocCompletionItem implements CompletionItem {
             }
         }
 
+        @Override
         public void processKeyEvent(KeyEvent evt) {
             // nothing special
         }
 
+        @Override
         public int getPreferredWidth(Graphics g, Font defaultFont) {
             return delegate.getPreferredWidth(g, defaultFont);
         }
 
-        public void render(Graphics g, Font defaultFont, Color defaultColor,
-                Color backgroundColor, int width, int height, boolean selected) {
-            
-            delegate.render(g, defaultFont, defaultColor, backgroundColor,
-                    width, height, selected);
+        @Override
+        public void render(Graphics g, Font defaultFont, Color defaultColor, Color backgroundColor, int width, int height, boolean selected) {
+            delegate.render(g, defaultFont, defaultColor, backgroundColor, width, height, selected);
         }
 
+        @Override
         public CompletionTask createDocumentationTask() {
             return delegate.createDocumentationTask();
         }
 
+        @Override
         public CompletionTask createToolTipTask() {
             return delegate.createToolTipTask();
         }
 
+        @Override
         public boolean instantSubstitution(JTextComponent component) {
             if (component != null) {
                 try {
@@ -359,14 +366,17 @@ final class JavadocCompletionItem implements CompletionItem {
             return true;
         }
 
+        @Override
         public int getSortPriority() {
             return delegate.getSortPriority();
         }
 
+        @Override
         public CharSequence getSortText() {
             return delegate.getSortText();
         }
 
+        @Override
         public CharSequence getInsertPrefix() {
             return delegate.getInsertPrefix();
         }
@@ -389,10 +399,12 @@ final class JavadocCompletionItem implements CompletionItem {
             this.delegate = item;
         }
         
+        @Override
         public void defaultAction(JTextComponent component) {
             delegate.defaultAction(component);
         }
 
+        @Override
         public void processKeyEvent(KeyEvent evt) {
             if (evt.getID() == KeyEvent.KEY_TYPED) {
                 if (Utilities.getJavadocCompletionSelectors().indexOf(evt.getKeyChar()) >= 0) {
@@ -406,37 +418,43 @@ final class JavadocCompletionItem implements CompletionItem {
             }
         }
 
+        @Override
         public int getPreferredWidth(Graphics g, Font defaultFont) {
             return delegate.getPreferredWidth(g, defaultFont);
         }
 
+        @Override
         public void render(Graphics g, Font defaultFont, Color defaultColor,
                 Color backgroundColor, int width, int height, boolean selected) {
-            
-            delegate.render(g, defaultFont, defaultColor, backgroundColor,
-                    width, height, selected);
+            delegate.render(g, defaultFont, defaultColor, backgroundColor, width, height, selected);
         }
 
+        @Override
         public CompletionTask createDocumentationTask() {
             return delegate.createDocumentationTask();
         }
 
+        @Override
         public CompletionTask createToolTipTask() {
             return delegate.createToolTipTask();
         }
 
+        @Override
         public boolean instantSubstitution(JTextComponent component) {
             return delegate.instantSubstitution(component);
         }
 
+        @Override
         public int getSortPriority() {
             return delegate.getSortPriority();
         }
 
+        @Override
         public CharSequence getSortText() {
             return delegate.getSortText();
         }
 
+        @Override
         public CharSequence getInsertPrefix() {
             return delegate.getInsertPrefix();
         }
diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java
index ffc908ac16..c276c07366 100644
--- a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java
+++ b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java
@@ -19,73 +19,15 @@
 
 package org.netbeans.modules.java.editor.javadoc;
 
-import com.sun.source.doctree.DocCommentTree;
-import com.sun.source.doctree.DocTree;
-import com.sun.source.doctree.DocTree.Kind;
-import com.sun.source.doctree.ErroneousTree;
-import com.sun.source.doctree.ParamTree;
-import com.sun.source.doctree.ReferenceTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.Scope;
-import com.sun.source.util.DocSourcePositions;
-import com.sun.source.util.DocTreeFactory;
-import com.sun.source.util.DocTreePath;
-import com.sun.source.util.DocTreePathScanner;
-import com.sun.source.util.DocTrees;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import static javax.lang.model.element.ElementKind.*;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
 import javax.swing.text.JTextComponent;
 import org.netbeans.api.editor.completion.Completion;
-import org.netbeans.api.java.lexer.JavadocTokenId;
-import org.netbeans.api.java.source.ClassIndex;
-import org.netbeans.api.java.source.ClasspathInfo;
-import org.netbeans.api.java.source.CompilationController;
-import org.netbeans.api.java.source.CompilationInfo;
-import org.netbeans.api.java.source.ElementHandle;
-import org.netbeans.api.java.source.ElementUtilities;
-import org.netbeans.api.java.source.JavaSource;
-import org.netbeans.api.java.source.Task;
-import org.netbeans.api.java.source.TreeUtilities;
-import org.netbeans.api.java.source.support.ReferencesCount;
-import org.netbeans.api.lexer.Token;
-import org.netbeans.api.lexer.TokenSequence;
-import org.netbeans.modules.editor.java.JavaCompletionItem;
-import org.netbeans.modules.editor.java.LazyJavaCompletionItem;
-import org.netbeans.modules.java.completion.Utilities;
-import org.netbeans.modules.java.editor.base.javadoc.JavadocCompletionUtils;
+import org.netbeans.modules.parsing.api.ParserManager;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.spi.ParseException;
 import org.netbeans.spi.editor.completion.CompletionItem;
 import org.netbeans.spi.editor.completion.CompletionProvider;
 import org.netbeans.spi.editor.completion.CompletionResultSet;
@@ -98,15 +40,11 @@ import org.openide.util.Exceptions;
  */
 final class JavadocCompletionQuery extends AsyncCompletionQuery{
     
-    private static final String CLASS_KEYWORD = "class"; //NOI18N
     private final int queryType;
     
     private int caretOffset;
     private List<CompletionItem> items;
-    private boolean hasAdditionalItems;
     private JTextComponent component;
-    private boolean ignoreCancel;
-    
 
     public JavadocCompletionQuery(int queryType) {
         this.queryType = queryType;
@@ -120,10 +58,28 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
     @Override
     protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) {
         try {
-            queryImpl(resultSet, doc, caretOffset);
-        } catch (InterruptedException ex) {
-            Exceptions.printStackTrace(ex);
-        } catch (ExecutionException ex) {
+            this.caretOffset = caretOffset;
+            items = null;
+            Source source = Source.create(doc);
+            if (source != null) {
+                if ((queryType & CompletionProvider.COMPLETION_QUERY_TYPE) != 0) {
+                    JavadocCompletionTask<CompletionItem> task = JavadocCompletionTask.create(caretOffset, new JavadocCompletionItem.Factory(),
+                            queryType == CompletionProvider.COMPLETION_ALL_QUERY_TYPE, this::isTaskCancelled);
+                    setCompletionHack(true);
+                    ParserManager.parse(Collections.singletonList(source), task);
+                    setCompletionHack(false);
+                    items = task.getResults();
+                    if (items != null) {
+                        resultSet.addAllItems(items);
+                    }
+                    resultSet.setHasAdditionalItems(task.hasAdditionalItems());
+                    int anchorOffset = task.getAnchorOffset();
+                    if (anchorOffset > -1) {
+                        resultSet.setAnchorOffset(anchorOffset);
+                    }
+                }
+            }
+        } catch (ParseException ex) {
             Exceptions.printStackTrace(ex);
         } finally {
             resultSet.finish();
@@ -155,41 +111,6 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         return true;
     }
 
-    static List<CompletionItem> runCompletionQuery(int queryType, Document doc, int caret) {
-        JavadocCompletionQuery q = new JavadocCompletionQuery(queryType);
-        JavadocContext jdctx = new JavadocContext();
-        
-        q.items = new  ArrayList<CompletionItem>();
-        q.caretOffset = caret;
-        q.ignoreCancel = true;
-        
-        q.runInJavac(JavaSource.forDocument(doc), jdctx);
-        
-        return q.items;
-    }
-    
-    private void queryImpl(CompletionResultSet resultSet, Document doc, int caretOffset) throws InterruptedException, ExecutionException {
-        JavadocContext jdctx = new JavadocContext();
-        items = new  ArrayList<CompletionItem>();
-        this.caretOffset = caretOffset;
-        runInJavac(JavaSource.forDocument(doc), jdctx);
-        
-        if (!ignoreCancel && isTaskCancelled()) {
-            return;
-        }
-        
-        if ((queryType & CompletionProvider.COMPLETION_QUERY_TYPE) != 0) {
-            if (!items.isEmpty()) {
-                resultSet.addAllItems(items);
-            }
-            resultSet.setHasAdditionalItems(hasAdditionalItems);
-        }
-        
-        if (jdctx.anchorOffset >= 0) {
-            resultSet.setAnchorOffset(jdctx.anchorOffset);
-        }
-    }
-
     /** #145615: this helps to work around the issue with stuck
      * {@code JavaSource.runWhenScanFinished}
      * It is copied from {@code JavaCompletionQuery}.
@@ -199,1215 +120,19 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
             component.putClientProperty("completion-active", flag); //NOI18N
         }
     }
-    
-    private void runInJavac(JavaSource js, final JavadocContext jdctx) {
-        try {
-            if (js == null) {
-                return;
-            }
-
-            js.runUserActionTask(new Task<CompilationController>() {
-
-                public void run(CompilationController javac) throws Exception {
-                    if (!ignoreCancel && isTaskCancelled()) {
-                        return;
-                    }
-                    if (!JavadocCompletionUtils.isJavadocContext(javac.getTokenHierarchy(), caretOffset)) {
-                        return;
-                    }
-                    setCompletionHack(true);
-                    JavaSource.Phase toPhase = javac.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
-                    if (toPhase != JavaSource.Phase.ELEMENTS_RESOLVED) {
-                        return;
-                    }
-                    try {
-                        jdctx.javac = javac;
-                        if (resolveContext(javac, jdctx)) {
-                            analyzeContext(jdctx);
-                        }
-                    } finally {
-                        jdctx.javac = null;
-                        if (component != null) {
-                            setCompletionHack(false);
-                        }
-                    }
-                }
-            }, true);
-        } catch (IOException ex) {
-            Exceptions.printStackTrace(ex);
-        }
-    }
-    
-    private boolean resolveContext(CompilationInfo javac, JavadocContext jdctx) throws IOException {
-        jdctx.doc = javac.getDocument();
-        // find class context: class, method, ...
-        DocTrees trees = javac.getDocTrees();
-        TreePath javadocFor = JavadocCompletionUtils.findJavadoc(javac, this.caretOffset);
-        if (javadocFor == null) {
-            return false;
-        }
-        jdctx.javadocFor = javadocFor;
-        DocCommentTree docCommentTree = trees.getDocCommentTree(javadocFor);
-        if (docCommentTree == null) {
-            return false;
-        }
-        jdctx.comment = docCommentTree;
-        Element elm = trees.getElement(javadocFor);
-        if (elm == null) {
-            return false;
-        }
-        jdctx.handle = ElementHandle.create(elm);
-        jdctx.commentFor = elm;
-        jdctx.jdts = JavadocCompletionUtils.findJavadocTokenSequence(javac, this.caretOffset);
-        if (jdctx.jdts == null) {
-            return false;
-        }
-        jdctx.positions = (DocSourcePositions) trees.getSourcePositions();
-        return jdctx.positions != null;
-    }
-    
-    private void analyzeContext(JavadocContext jdctx) {
-        TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
-        if (jdts == null) {
-            return;
-        }
-        
-        jdts.move(this.caretOffset);
-        if (!jdts.moveNext() && !jdts.movePrevious()) {
-            // XXX solve /***/
-            // provide block tags, inline tags, html
-            return;
-        }
-        
-        if (this.caretOffset - jdts.offset() == 0) {
-            // if position in token == 0 resolve CC according to previous token
-            jdts.movePrevious();
-        }
-        
-        switch (jdts.token().id()) {
-            case TAG:
-                resolveTagToken(jdctx);
-                break;
-            case IDENT:
-                resolveIdent(jdctx);
-                break;
-            case DOT:
-                resolveDotToken(jdctx);
-                break;
-            case HASH:
-                resolveHashToken(jdctx);
-                break;
-            case OTHER_TEXT:
-                resolveOtherText(jdctx, jdts);
-                break;
-            case HTML_TAG:
-                resolveHTMLToken(jdctx);
-                break;
-        }
-    }
-
-    void resolveTagToken(JavadocContext jdctx) {
-        assert jdctx.jdts.token() != null;
-        assert jdctx.jdts.token().id() == JavadocTokenId.TAG;
-
-        DocTreePath tag = getTag(jdctx, caretOffset);
-        if (tag == null) {
-            // eg * description @
-            return;
-        }
-        if (JavadocCompletionUtils.isBlockTag(tag)) {
-            resolveBlockTag(tag, jdctx);
-        } else {
-            resolveInlineTag(tag, jdctx);
-        }
-    }
-    
-    void resolveBlockTag(DocTreePath tag, JavadocContext jdctx) {
-        int pos;
-        String prefix;
-        if (tag != null) {
-            pos = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-            prefix = JavadocCompletionUtils.getCharSequence(jdctx.doc, pos, caretOffset).toString();
-        } else {
-            prefix = ""; // NOI18N
-            pos = caretOffset;
-        }
-        
-        items.addAll(JavadocCompletionItem.addBlockTagItems(jdctx.handle.getKind(), prefix, pos));
-        jdctx.anchorOffset = pos;
-    }
-    
-    void resolveInlineTag(DocTreePath tag, JavadocContext jdctx) {
-        int pos;
-        String prefix;
-        if (tag != null) {
-            pos = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf()) + 1;
-            prefix = JavadocCompletionUtils.getCharSequence(jdctx.doc, pos, caretOffset).toString();
-            jdctx.anchorOffset = pos;
-        } else {
-            pos = caretOffset;
-            prefix = ""; // NOI18N
-            jdctx.anchorOffset = pos;
-        }
-        items.addAll(JavadocCompletionItem.addInlineTagItems(jdctx.handle.getKind(), prefix, pos));
-    }
-
-    private int skipWhitespacesBackwards(final JavadocContext jdctx, final int offset) {
-        jdctx.jdts.move(offset);
-        
-        while (jdctx.jdts.movePrevious()) {
-            Token t = jdctx.jdts.token();
-            
-            if (t.id() != JavadocTokenId.OTHER_TEXT) return jdctx.jdts.offset();
-            
-            CharSequence text = t.text();
-            
-            for (int i = 0; i < text.length(); i++) {
-                if (!Character.isWhitespace(text.charAt(i))) {
-                    //XXX: does not handle the leading '*' correctly
-                     return jdctx.jdts.offset();
-                }
-            }
-        }
-        
-        return jdctx.jdts.moveNext() ? jdctx.jdts.offset() : offset;
-    }
-    
-    private DocTreePath getTag(final JavadocContext jdctx, final int offset) {
-        final DocTreePath[] result = new DocTreePath[1];
-        final int normalizedOffset = skipWhitespacesBackwards(jdctx, offset);
-        new DocTreePathScanner<Void, Void>() {
-            @Override public Void scan(DocTree node, Void p) {
-                if (   node != null
-                    && jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) <= normalizedOffset
-                    && jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) >= normalizedOffset) {
-                    result[0] = new DocTreePath(getCurrentPath(), node);
-                    return super.scan(node, p);
-                }
-                
-                return null;
-            }
-        }.scan(new DocTreePath(jdctx.javadocFor, jdctx.comment), null);
-        
-        return result[0];
-    }
-    
-    private static final Set<ElementKind> EXECUTABLE = EnumSet.of(ElementKind.METHOD, ElementKind.CONSTRUCTOR);
-    
-    void resolveIdent(JavadocContext jdctx) {
-        TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
-        assert jdts.token() != null;
-        assert jdts.token().id() == JavadocTokenId.IDENT;
-        // @see package.Class[.NestedClass]#member[()]
-        // START -> TAG OT(WS+) MEMBER_SELECT|CLASS_SELECT
-        // CLASS_SELECT -> IDENT | IDENT DOT CLASS_SELECT | IDENT MEMBER_SELECT
-        // MEMBER_SELECT -> HASH IDENT OT('(')
-        
-        // @see org.Clazz#meth(int p, int q)
-        // TAG OT(' ') IDENT DOT IDENT HASH IDENT OT('(') IDENT OT(' ') IDENT OT(', ') IDENT OT(' ') IDENT OT(')\n...')
-        // @see Clazz#meth(int p, int q)
-        // @see #meth(int p, int q)
-        // @see Clazz.NestedClazz
-        
-        // Parenthesis content:
-        // param types not neccessary to be imported or fqn!!!
-        // param types may be fqn
-        // param types never contains generics
-        // params may contain name but they not necessary match the real names
-        // param list may contain spaces
-        // no space allowed between member and parenthesis
-        
-        DocTreePath tag = getTag(jdctx, caretOffset);
-        if (tag != null) {
-            insideTag(tag, jdctx);
-        }
-    }
-    
-    void resolveDotToken(JavadocContext jdctx) {
-        assert jdctx.jdts.token() != null;
-        assert jdctx.jdts.token().id() == JavadocTokenId.DOT;
-
-        DocTreePath tag = getTag(jdctx, caretOffset);
-        if (tag != null) {
-            insideTag(tag, jdctx);
-        }
-    }
-    
-    void resolveHashToken(JavadocContext jdctx) {
-        assert jdctx.jdts.token() != null;
-        assert jdctx.jdts.token().id() == JavadocTokenId.HASH;
-
-        DocTreePath tag = getTag(jdctx, caretOffset);
-        if (tag != null) {
-            insideTag(tag, jdctx);
-        }
-    }
-    
-    void resolveHTMLToken(JavadocContext jdctx) {
-        assert jdctx.jdts.token() != null;
-        assert jdctx.jdts.token().id() == JavadocTokenId.HTML_TAG;
-
-        DocTreePath tag = getTag(jdctx, caretOffset);
-        if (tag != null && tag.getLeaf().getKind() == Kind.PARAM) {
-            // type param
-            insideParamTag(tag, jdctx);
-        }
-    }
-    
-    private void insideTag(DocTreePath tag, JavadocContext jdctx) {
-        switch (JavadocCompletionUtils.normalizedKind(tag.getLeaf())) {
-            case IDENTIFIER:
-                if (tag.getParentPath() == null || tag.getParentPath().getLeaf().getKind() != Kind.PARAM)
-                    break;
-                tag = tag.getParentPath();
-                //intentional fall-through:
-            case PARAM:
-                insideParamTag(tag, jdctx);
-                break;
-            case SEE: case THROWS: case VALUE:
-            case LINK: case LINK_PLAIN://XXX: was only unclosed???
-                insideSeeTag(tag, jdctx);
-                break;
-            case REFERENCE:
-                insideReference(tag, jdctx);
-                break;
-        }
-    }
-    
-    private void insideSeeTag(DocTreePath tag, JavadocContext jdctx) {
-        TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
-        assert jdts.token() != null;
-        int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-        
-        boolean isThrowsKind = JavadocCompletionUtils.normalizedKind(tag.getLeaf()) == Kind.THROWS;
-        if (isThrowsKind && !(EXECUTABLE.contains(jdctx.commentFor.getKind()))) {
-            // illegal tag in this context
-            return;
-        }
-        
-        jdts.move(start + (JavadocCompletionUtils.isBlockTag(tag)? 0: 1));
-        // @see|@link|@throws
-        if (!jdts.moveNext() || caretOffset <= jdts.offset() + jdts.token().length()) {
-            return;
-        }
-        // white space
-        if (!jdts.moveNext() || caretOffset <= jdts.offset()) {
-            return;
-        }
-        
-        boolean noPrefix = false;
-        
-        if (caretOffset <= jdts.offset() + jdts.token().length()) {
-            int pos = caretOffset - jdts.offset();
-            CharSequence cs = jdts.token().text();
-            cs = pos < cs.length()? cs.subSequence(0, pos): cs;
-            
-            if (JavadocCompletionUtils.isWhiteSpace(cs)
-                    || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
-                noPrefix = true;
-            } else {
-                // broken syntax
-                return;
-            }
-        } else if (! (JavadocCompletionUtils.isWhiteSpace(jdts.token())
-                || JavadocCompletionUtils.isLineBreak(jdts.token()) )) {
-            // not java reference
-            return;
-        } else if (jdts.moveNext()) {
-            int end = (int) jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-            insideReference(JavadocCompletionUtils.normalizedKind(tag.getLeaf()), jdts.offset(), end, jdctx);
-        }
-        
-        if (noPrefix) {
-            // complete all types + members
-            
-            if (isThrowsKind) {
-                completeThrowsOrPkg(null, "", caretOffset, jdctx); // NOI18N
-            } else {
-                completeClassOrPkg(null, "", caretOffset, jdctx); // NOI18N
-            }
-            jdctx.anchorOffset = caretOffset;
-            return;
-        }
-    }
-    
-    private void insideReference(DocTreePath tag, JavadocContext jdctx) {
-        ReferenceTree ref = (ReferenceTree) tag.getLeaf();
-        Kind kind = tag.getParentPath().getLeaf().getKind();
-        int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, ref);
-        int end   = (int) jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, ref);
-
-        insideReference(kind, start, end, jdctx);
-    }
-
-    private void insideReference(Kind enclosingKind, int start, int end, JavadocContext jdctx) {
-        // complete type
-        CharSequence cs = JavadocCompletionUtils.getCharSequence(jdctx.doc, start, end);
-        StringBuilder sb = new StringBuilder();
-        for (int i = caretOffset - start - 1; i >= 0; i--) {
-            char c = cs.charAt(i);
-            if (c == '#') {
-                // complete class member
-                String prefix = sb.toString();
-                int substitutionOffset = caretOffset - sb.length();
-                jdctx.anchorOffset = substitutionOffset;
-                if (i == 0) {
-                    if (enclosingKind == Kind.VALUE) {
-                        addLocalConstants(jdctx, prefix, substitutionOffset);
-                    } else {
-                        addLocalMembersAndVars(jdctx, prefix, substitutionOffset);
-                    }
-                } else {
-                    TypeElement scopeType = jdctx.commentFor.getKind().isClass() || jdctx.commentFor.getKind().isInterface() ? (TypeElement) jdctx.commentFor
-                                                                                                                             : jdctx.javac.getElementUtilities().enclosingTypeElement(jdctx.commentFor);
-                    TypeMirror type = 
-                            jdctx.javac.getTreeUtilities().parseType(cs.subSequence(0, i).toString(), scopeType);
-                    if (enclosingKind == Kind.VALUE) {
-                        addMemberConstants(jdctx, prefix, substitutionOffset, type);
-                    } else {
-                        addMembers(jdctx, prefix, substitutionOffset, type, jdctx.javac.getTypes().asElement(type),
-                                EnumSet.<ElementKind>of(ENUM_CONSTANT, FIELD, METHOD, CONSTRUCTOR),
-                                null);
-                    }
-                }
-                return;
-            } else if (c == '.') {
-                // complete class or package
-                String prefix = sb.toString();
-                String fqn = cs.subSequence(0, i).toString();
-                int substitutionOffset = caretOffset - sb.length();
-                jdctx.anchorOffset = substitutionOffset;
-                if (enclosingKind == Kind.THROWS) {
-                    completeThrowsOrPkg(fqn, prefix, substitutionOffset, jdctx);
-                } else {
-                    completeClassOrPkg(fqn, prefix, substitutionOffset, jdctx);
-                }
-                return;
-            } else {
-                sb.insert(0, c);
-            }
-        }
-        // complete class or package
-        String prefix = sb.toString();
-        String fqn = null;
-        int substitutionOffset = caretOffset - sb.length();
-        jdctx.anchorOffset = substitutionOffset;
-        if (enclosingKind == Kind.THROWS) {
-            completeThrowsOrPkg(fqn, prefix, substitutionOffset, jdctx);
-        } else {
-            completeClassOrPkg(fqn, prefix, substitutionOffset, jdctx);
-        }
-    }
-    
-    private void insideParamTag(DocTreePath tag, JavadocContext jdctx) {
-        TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
-        assert jdts.token() != null;
-        int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-        
-        jdts.move(start);
-        // @param
-        if (!jdts.moveNext() || caretOffset <= jdts.offset() + jdts.token().length()) {
-            return;
-        }
-        // white space
-        if (!jdts.moveNext() || caretOffset <= jdts.offset()) {
-            return;
-        }
-        
-        if (caretOffset <= jdts.offset() + jdts.token().length()) {
-            int pos = caretOffset - jdts.offset();
-            CharSequence cs = jdts.token().text();
-            cs = pos < cs.length()? cs.subSequence(0, pos): cs;
-            
-            if (JavadocCompletionUtils.isWhiteSpace(cs)
-                    || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
-                // none prefix
-                jdctx.anchorOffset = caretOffset;
-                completeParamName(tag, "", caretOffset, jdctx); // NOI18N
-                return;
-            } else {
-                // broken syntax
-                return;
-            }
-        }
-        
-        jdts.moveNext(); // param name
-        if (!(jdts.token().id() == JavadocTokenId.IDENT || jdts.token().id() == JavadocTokenId.HTML_TAG)) {
-            // broken syntax
-            return;
-        }
-        if (caretOffset <= jdts.offset() + jdts.token().length()) {
-            CharSequence prefix = jdts.token().text().subSequence(0, caretOffset - jdts.offset());
-            jdctx.anchorOffset = jdts.offset();
-            completeParamName(tag, prefix.toString(), jdts.offset(), jdctx);
-            return;
-        }
-    }
-    
-    private void completeParamName(DocTreePath tag, String prefix, int substitutionOffset, JavadocContext jdctx) {
-        if (EXECUTABLE.contains(jdctx.commentFor.getKind())) {
-            List<? extends DocTree> blockTags = jdctx.comment.getBlockTags();
-            ExecutableElement method = (ExecutableElement) jdctx.commentFor;
-            for (VariableElement param : method.getParameters()) {
-                String name = param.getSimpleName().toString();
-
-                if (!containsParam(blockTags, name) && name.startsWith(prefix)) {
-                    items.add(JavadocCompletionItem.createNameItem(name, substitutionOffset));
-                }
-            }
-            
-            completeTypeVarName(jdctx.commentFor, prefix, substitutionOffset);
-        } else if (jdctx.commentFor.getKind().isClass() || jdctx.commentFor.getKind().isInterface()) {
-            completeTypeVarName(jdctx.commentFor, prefix, substitutionOffset);
-        }
-    }
 
-    private boolean containsParam(List<? extends DocTree> blockTags, String name) {
-        for (DocTree blockTag : blockTags) {
-            if(blockTag.getKind() == Kind.PARAM) {
-                ParamTree param = (ParamTree) blockTag;
-                if(name.contentEquals(param.getName().getName())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private void completeTypeVarName(Element forElement, String prefix, int substitutionOffset) {
-        if (prefix.length() > 0) {
-            if (prefix.charAt(0) == '<') {
-                prefix = prefix.substring(1, prefix.length());
-            } else {
-                // not type param
-                return;
-            }
-        }
-        List<? extends TypeParameterElement> tparams = (forElement.getKind().isClass() || forElement.getKind().isInterface())
-             ? ((TypeElement) forElement).getTypeParameters()
-             : ((ExecutableElement) forElement).getTypeParameters();
-        
-        for (TypeParameterElement typeVariable : tparams) {
-            String name = typeVariable.getSimpleName().toString();
-            if (name.startsWith(prefix)) {
-                items.add(JavadocCompletionItem.createNameItem(
-                        '<' + name + '>', substitutionOffset));
-            }
-        }
-    }
-    
-    private void completeClassOrPkg(String fqn, String prefix, int substitutionOffset, JavadocContext jdctx) {
-        String pkgPrefix;
-        if (fqn == null) {
-            pkgPrefix = prefix;
-            addTypes(EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
-                    null, null, prefix, substitutionOffset, jdctx);
-            
-        } else {
-            pkgPrefix = fqn + '.' + prefix;
-            PackageElement pkgElm = jdctx.javac.getElements().getPackageElement(fqn);
-            if (pkgElm != null) {
-                addPackageContent(pkgElm,
-                        EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
-                        null, null, prefix, substitutionOffset, jdctx);
-            }
-            
-            TypeElement typeElm = jdctx.javac.getElements().getTypeElement(fqn);
-            if (typeElm != null) {
-                // inner classes
-                addInnerClasses(typeElm,
-                        EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
-                        null, null, prefix, substitutionOffset, jdctx);
-            }
-        }
-        
-        for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class)))
-            if (pkgName.length() > 0 && !Utilities.isExcluded(pkgName + "."))
-                items.add(JavaCompletionItem.createPackageItem(pkgName, substitutionOffset, false));
-    }
-    
-    private void completeThrowsOrPkg(String fqn, String prefix, int substitutionOffset, JavadocContext jdctx) {
-        final Elements elements = jdctx.javac.getElements();
-        final Set<Element> excludes = new HashSet<Element>();
-        String pkgPrefix;
-        
-        // add declared Throwables        
-        ExecutableElement method = (ExecutableElement) jdctx.commentFor;
-        for (TypeMirror type : method.getThrownTypes()) {
-            if (type.getKind() != TypeKind.DECLARED) continue;
-            TypeElement clazz = (TypeElement) ((DeclaredType) type).asElement();
-            String typeName = clazz.getSimpleName().toString();
-            if (startsWith(typeName, prefix)) {
-                String qualTypeName = clazz.getQualifiedName().toString();
-                TypeElement typeElement = elements.getTypeElement(qualTypeName);
-                if (typeElement == null) {
-                    continue;
-                }
-                items.add(JavaCompletionItem.createTypeItem(
-                        jdctx.javac, typeElement, (DeclaredType) typeElement.asType(),
-                        substitutionOffset, /*XXX:*/typeName != qualTypeName ? jdctx.getReferencesCount() : null,
-                        elements.isDeprecated(typeElement), false, false, false, true, false, null));
-                excludes.add(typeElement);
-            }
-        }
-
-        // add other Throwables        
-        if (fqn == null) {
-            pkgPrefix = prefix;
-            addTypes(EnumSet.<ElementKind>of(CLASS),
-                    findDeclaredType("java.lang.Throwable", elements), // NOI18N
-                    excludes, prefix, substitutionOffset, jdctx);
-            
-        } else {
-            pkgPrefix = fqn + '.' + prefix;
-            
-            PackageElement pkgElm = elements.getPackageElement(fqn);
-            if (pkgElm != null) {
-                addPackageContent(pkgElm,
-                        EnumSet.<ElementKind>of(CLASS),
-                        findDeclaredType("java.lang.Throwable", elements), // NOI18N
-                        excludes, prefix, substitutionOffset, jdctx);
-            }
-            
-            TypeElement typeElm = elements.getTypeElement(fqn);
-            if (typeElm != null) {
-                // inner classes
-                addInnerClasses(typeElm,
-                        EnumSet.<ElementKind>of(CLASS),
-                        findDeclaredType("java.lang.Throwable", elements), // NOI18N
-                        excludes, prefix, substitutionOffset, jdctx);
-            }
-        }
-        
-        
-        // add packages
-        
-        for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class)))
-            if (pkgName.length() > 0)
-                items.add(JavaCompletionItem.createPackageItem(pkgName, substitutionOffset, false));
-    }
-    
-    private static DeclaredType findDeclaredType(CharSequence fqn, Elements elements) {
-        TypeElement re = elements.getTypeElement(fqn);
-        if (re != null) {
-            TypeMirror asType = re.asType();
-            if (asType.getKind() == TypeKind.DECLARED) {
-                return (DeclaredType) asType;
-            }
-        }
-        return null;
-    }
-    
-    private void addMembers(final JavadocContext env, final String prefix, final int substitutionOffset, final TypeMirror type, final Element elem, final EnumSet<ElementKind> kinds, final DeclaredType baseType) {
-        Set<? extends TypeMirror> smartTypes = /*queryType == COMPLETION_QUERY_TYPE ? env.getSmartTypes() :*/ null;
-        final CompilationInfo controller = env.javac;
-        final Trees trees = controller.getTrees();
-        final Elements elements = controller.getElements();
-        final Types types = controller.getTypes();
-        final TreeUtilities tu = controller.getTreeUtilities();
-        final ElementUtilities eu = controller.getElementUtilities();
-        TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement)((DeclaredType)type).asElement() : null;
-//        final boolean isStatic = elem != null && (elem.getKind().isClass() || elem.getKind().isInterface() || elem.getKind() == TYPE_PARAMETER);
-//        final boolean isSuperCall = elem != null && elem.getKind().isField() && elem.getSimpleName().contentEquals(SUPER_KEYWORD);
-        Element docelm = env.handle.resolve(controller);
-        TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
-        final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
-        TypeElement enclClass = scope.getEnclosingClass();
-        final TypeMirror enclType = enclClass != null ? enclClass.asType() : null;
-        ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
-            public boolean accept(Element e, TypeMirror t) {
-                switch (e.getKind()) {
-                    case FIELD:
-                        String name = e.getSimpleName().toString();
-                        return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
-                                &&  (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
-//                                &&
-//                                isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
-//                                tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t) && 
-//                                (!isStatic || e.getModifiers().contains(Modifier.STATIC)) &&
-//                                (isStatic || !e.getSimpleName().contentEquals(THIS_KEYWORD)) &&
-//                                ((isStatic && !inImport) /*|| !e.getSimpleName().contentEquals(CLASS_KEYWORD)*/);
-                    case ENUM_CONSTANT:
-                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-//                                isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
-                    case METHOD:
-                        String sn = e.getSimpleName().toString();
-                        return Utilities.startsWith(sn, prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-                                (!Utilities.isExcludeMethods() || !Utilities.isExcluded(eu.getElementName(e.getEnclosingElement(), true) + "." + sn)); //NOI18N
-//                                &&
-//                                isOfKindAndType(((ExecutableType)asMemberOf(e, t, types)).getReturnType(), e, kinds, baseType, scope, trees, types) &&
-//                                (isSuperCall && e.getModifiers().contains(PROTECTED) || tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t)) &&
-//                                (!isStatic || e.getModifiers().contains(Modifier.STATIC));
-//                    case CLASS:
-//                    case ENUM:
-//                    case INTERFACE:
-//                    case ANNOTATION_TYPE:
-//                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-//                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-//                                isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types) &&
-//                                tu.isAccessible(scope, e, t) && isStatic;
-                    case CONSTRUCTOR:
-                        return (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-//                                isOfKindAndType(e.getEnclosingElement().asType(), e, kinds, baseType, scope, trees, types) &&
-                                (trees.isAccessible(scope, e, (DeclaredType)t) || (elem.getModifiers().contains(Modifier.ABSTRACT) && !e.getModifiers().contains(Modifier.PRIVATE)));
-//                                &&
-//                                isStatic;
-                }
-                return false;
-            }
-        };
-        for(Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
-            switch (e.getKind()) {
-                case ENUM_CONSTANT:
-                case FIELD:
-                    TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType();
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement) e, tm, null, substitutionOffset, null, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), /*isOfSmartType(env, tm, smartTypes)*/false, -1, null));
-                    break;
-                case CONSTRUCTOR:
-                case METHOD:
-                    ExecutableType et = (ExecutableType)(type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType());
-//                    items.add(JavaCompletionItem.createExecutableItem((ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), inImport, /*isOfSmartType(env, et.getReturnType(), smartTypes)*/false));
-                    items.add(JavadocCompletionItem.createExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e)));
-                    break;
-//                case CLASS:
-//                case ENUM:
-//                case INTERFACE:
-//                case ANNOTATION_TYPE:
-//                    DeclaredType dt = (DeclaredType)(type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType());
-//                    results.add(JavaCompletionItem.createTypeItem((TypeElement)e, dt, anchorOffset, false, elements.isDeprecated(e), insideNew, false));
-//                    break;
-            }
-        }
-    }
-
-    private void addMemberConstants(final JavadocContext env, final String prefix, final int substitutionOffset, final TypeMirror type) {
-        final CompilationInfo controller = env.javac;
-        final Trees trees = controller.getTrees();
-        final Elements elements = controller.getElements();
-        final Types types = controller.getTypes();
-        final TreeUtilities tu = controller.getTreeUtilities();
-        TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement)((DeclaredType)type).asElement() : null;
-        Element docelm = env.handle.resolve(controller);
-        TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
-        final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
-        ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
-            public boolean accept(Element e, TypeMirror t) {
-                switch (e.getKind()) {
-                    case FIELD:
-                        String name = e.getSimpleName().toString();
-                        return ((VariableElement)e).getConstantValue() != null
-                                && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
-                                && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
-                    case ENUM_CONSTANT:
-                        return ((VariableElement)e).getConstantValue() != null &&
-                                Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
-                }
-                return false;
-            }
-        };
-        for(Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
-            switch (e.getKind()) {
-                case ENUM_CONSTANT:
-                case FIELD:
-                    TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType();
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement) e, tm, null, substitutionOffset, null, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), /*isOfSmartType(env, tm, smartTypes)*/false, -1, null));
-                    break;
-            }
-        }
-    }
-
-    private void addLocalConstants(final JavadocContext env, final String prefix, final int substitutionOffset) {
-        final CompilationInfo controller = env.javac;
-        final Elements elements = controller.getElements();
-        final Types types = controller.getTypes();
-        final TreeUtilities tu = controller.getTreeUtilities();
-        final Trees trees = controller.getTrees();
-        Element docelm = env.handle.resolve(controller);
-        TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
-        final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
-        final TypeElement enclClass = scope.getEnclosingClass();
-        ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
-            public boolean accept(Element e, TypeMirror t) {
-                switch (e.getKind()) {
-                    case FIELD:
-                        String name = e.getSimpleName().toString();
-                        return ((VariableElement)e).getConstantValue() != null
-                                && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
-                                &&  (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
-                    case ENUM_CONSTANT:
-                        return ((VariableElement)e).getConstantValue() != null &&
-                                Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
-                }
-                return false;
-            }
-        };
-        for (Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
-            switch (e.getKind()) {
-                case ENUM_CONSTANT:
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, e.asType(), null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, e.asType(), smartTypes)*/, -1, null));
-                    break;
-                case FIELD:
-                    TypeMirror tm = asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, tm, null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, tm, smartTypes)*/, -1, null));
-                    break;
-            }
-        }
-    }
-
-    private void addLocalMembersAndVars(final JavadocContext env, final String prefix, final int substitutionOffset) {
-        final CompilationInfo controller = env.javac;
-        final Elements elements = controller.getElements();
-        final Types types = controller.getTypes();
-        final TreeUtilities tu = controller.getTreeUtilities();
-        final Trees trees = controller.getTrees();
-        Element docelm = env.handle.resolve(controller);
-        TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
-        final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
-        Set<? extends TypeMirror> smartTypes = null;
-//        if (queryType == COMPLETION_QUERY_TYPE) {
-//            smartTypes = env.getSmartTypes();
-//            if (smartTypes != null) {
-//                for (TypeMirror st : smartTypes) {
-//                    if (st.getKind().isPrimitive())
-//                        st = types.boxedClass((PrimitiveType)st).asType();
-//                    if (st.getKind() == TypeKind.DECLARED) {
-//                        final DeclaredType type = (DeclaredType)st;
-//                        final TypeElement element = (TypeElement)type.asElement();
-//                        if (withinScope(env, element))
-//                            continue;
-//                        final boolean isStatic = element.getKind().isClass() || element.getKind().isInterface();
-//                        final Set<? extends TypeMirror> finalSmartTypes = smartTypes;
-//                        ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
-//                            public boolean accept(Element e, TypeMirror t) {
-//                                return (!isStatic || e.getModifiers().contains(STATIC)) &&
-//                                        Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-//                                        tu.isAccessible(scope, e, t) &&
-//                                        (e.getKind().isField() && isOfSmartType(env, ((VariableElement)e).asType(), finalSmartTypes) || e.getKind() == METHOD && isOfSmartType(env, ((ExecutableElement)e).getReturnType(), finalSmartTypes));
-//                            }
-//                        };
-//                        for (Element ee : controller.getElementUtilities().getMembers(type, acceptor)) {
-//                            if (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(ee))
-//                                results.add(JavaCompletionItem.createStaticMemberItem(type, ee, types.asMemberOf(type, ee), anchorOffset, elements.isDeprecated(ee)));
-//                        }
-//                    }
-//                }
-//            }
-//        }
-        final TypeElement enclClass = scope.getEnclosingClass();
-//        final boolean isStatic = enclClass == null ? false :
-//            (tu.isStaticContext(scope) || (env.getPath().getLeaf().getKind() == Tree.Kind.BLOCK && ((BlockTree)env.getPath().getLeaf()).isStatic()));
-//        final Collection<? extends Element> illegalForwardRefs = env.getForwardReferences();
-        final ExecutableElement method = scope.getEnclosingMethod();
-        ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
-            public boolean accept(Element e, TypeMirror t) {
-                switch (e.getKind()) {
-                    case CONSTRUCTOR:
-                        return Utilities.startsWith(e.getEnclosingElement().getSimpleName().toString(), prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-//                                (!isStatic || e.getModifiers().contains(STATIC)) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
-//                    case LOCAL_VARIABLE:
-//                    case EXCEPTION_PARAMETER:
-//                    case PARAMETER:
-//                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-//                                (method == e.getEnclosingElement() || e.getModifiers().contains(FINAL) ||
-//                                (method == null && (e.getEnclosingElement().getKind() == INSTANCE_INIT ||
-//                                e.getEnclosingElement().getKind() == STATIC_INIT))) &&
-//                                !illegalForwardRefs.contains(e);
-                    case FIELD:
-//                        if (e.getSimpleName().contentEquals(THIS_KEYWORD) || e.getSimpleName().contentEquals(SUPER_KEYWORD))
-//                            return Utilities.startsWith(e.getSimpleName().toString(), prefix) && !isStatic;
-                        String name = e.getSimpleName().toString();
-                        return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
-                                &&  (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
-//                        String name = e.getSimpleName().toString();
-//                        return !name.equals(THIS_KEYWORD) && !name.equals(SUPER_KEYWORD)
-//                                && Utilities.startsWith(name, prefix);
-                    case ENUM_CONSTANT:
-                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-//                                !illegalForwardRefs.contains(e) &&
-//                                (!isStatic || e.getModifiers().contains(STATIC)) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
-                    case METHOD:
-                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-//                                (!isStatic || e.getModifiers().contains(STATIC)) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
-                }
-                return false;
-            }
-        };
-        for (Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
-            switch (e.getKind()) {
-                case ENUM_CONSTANT:
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, e.asType(), null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, e.asType(), smartTypes)*/, -1, null));
-                    break;
-                case FIELD:
-                    String name = e.getSimpleName().toString();
-                    TypeMirror tm = asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, tm, null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, tm, smartTypes)*/, -1, null));
-                    break;
-                case CONSTRUCTOR:
-                case METHOD:
-                    ExecutableType et = (ExecutableType)asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
-//                    items.add(JavaCompletionItem.createExecutableItem((ExecutableElement)e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false, false/*isOfSmartType(env, et.getReturnType(), smartTypes)*/));
-                    items.add(JavadocCompletionItem.createExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
-                    break;
-            }
-        }
-    }
-
-    private static TypeMirror asMemberOf(Element element, TypeMirror type, Types types) {
-        TypeMirror ret = element.asType();
-        TypeMirror enclType = element.getEnclosingElement().asType();
-        if (enclType.getKind() == TypeKind.DECLARED)
-            enclType = types.erasure(enclType);
-        while(type != null && type.getKind() == TypeKind.DECLARED) {
-            if (types.isSubtype(type, enclType)) {
-                ret = types.asMemberOf((DeclaredType)type, element);
-                break;
-            }
-            type = ((DeclaredType)type).getEnclosingType();
-        }
-        return ret;
-    }       
-    
-    private void addTypes(EnumSet<ElementKind> kinds, DeclaredType baseType,
-            Set<? extends Element> toExclude, String prefix,
-            int substitutionOffset, JavadocContext jdctx) {
-        
-        if (queryType == CompletionProvider.COMPLETION_ALL_QUERY_TYPE) {
-            if (baseType == null) {
-                addAllTypes(jdctx, kinds, toExclude, prefix, substitutionOffset);
-            } else {
-                Elements elements = jdctx.javac.getElements();
-                for(DeclaredType subtype : getSubtypesOf(baseType, prefix, jdctx)) {
-                    TypeElement elem = (TypeElement)subtype.asElement();
-                    if ((toExclude == null || !toExclude.contains(elem)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(elem)))
-                        items.add(JavaCompletionItem.createTypeItem(jdctx.javac, elem, subtype, substitutionOffset, jdctx.getReferencesCount(), elements.isDeprecated(elem), false, false, false, false, false, null));
-                }
-            }
-        } else {
-            addLocalAndImportedTypes(jdctx, kinds, baseType, toExclude, prefix, substitutionOffset);
-            hasAdditionalItems = true;
-        }
-    }
-
-    private void addLocalAndImportedTypes(final JavadocContext env, final EnumSet<ElementKind> kinds, final DeclaredType baseType, final Set<? extends Element> toExclude, final String prefix, int substitutionOffset) {
-        final CompilationInfo controller = env.javac;
-        final Trees trees = controller.getTrees();
-        final Elements elements = controller.getElements();
-        final Types types = controller.getTypes();
-        final TreeUtilities tu = controller.getTreeUtilities();
-        Element docelm = env.handle.resolve(controller);
-        TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
-        final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
-        final TypeElement enclClass = scope.getEnclosingClass();
-        final boolean isStatic = enclClass == null ? false : tu.isStaticContext(scope);
-        ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
-            public boolean accept(Element e, TypeMirror t) {
-                if ((toExclude == null || !toExclude.contains(e)) && (e.getKind().isClass() || e.getKind().isInterface() || e.getKind() == TYPE_PARAMETER)) {
-                    String name = e.getSimpleName().toString();
-                    return name.length() > 0 && !Character.isDigit(name.charAt(0)) && startsWith(name, prefix) &&
-                            (!isStatic || e.getModifiers().contains(Modifier.STATIC)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
-                }
-                return false;
-            }
-        };
-        for(Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
-            switch (e.getKind()) {
-                case CLASS:
-                case ENUM:
-                case INTERFACE:
-                case ANNOTATION_TYPE:
-                    items.add(JavadocCompletionItem.createTypeItem(env.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)));
-                    break;
-            }                
-        }
-        acceptor = new ElementUtilities.ElementAcceptor() {
-            public boolean accept(Element e, TypeMirror t) {
-                if ((e.getKind().isClass() || e.getKind().isInterface())) {
-                    return (toExclude == null || !toExclude.contains(e)) && startsWith(e.getSimpleName().toString(), prefix) &&
-                            (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement)e) &&
-                            isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
-                }
-                return false;
-            }
-        };
-        for (TypeElement e : controller.getElementUtilities().getGlobalTypes(acceptor)) {
-            items.add(JavadocCompletionItem.createTypeItem(env.javac, e, substitutionOffset, null, elements.isDeprecated(e)));
-        }
-    }
-
-    private void addAllTypes(JavadocContext env, EnumSet<ElementKind> kinds, Set<? extends Element> toExclude, String prefix, int substitutionOffset) {
-//        String prefix = env.getPrefix();
-        CompilationInfo controller = env.javac;
-        boolean isCaseSensitive = false;
-        ClassIndex.NameKind kind = 
-            isCaseSensitive? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
-//        ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
-//            Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE :
-//            Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
-        Set<ElementHandle<Element>> excludeHandles = null;
-        if (toExclude != null) {
-            excludeHandles = new HashSet<ElementHandle<Element>>(toExclude.size());
-            for (Element el : toExclude) {
-                excludeHandles.add(ElementHandle.create(el));
-            }
-        }
-        for(ElementHandle<TypeElement> name : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
-            if ((excludeHandles == null || !excludeHandles.contains(name)) && !isAnnonInner(name)) {
-                items.add(LazyJavaCompletionItem.createTypeItem(name, kinds, substitutionOffset, env.getReferencesCount(), controller.getSnapshot().getSource(), false, false, false, null));
-            }
-        }
-    }
-        
-    private void addInnerClasses(TypeElement te, EnumSet<ElementKind> kinds, DeclaredType baseType, Set<? extends Element> toExclude, String prefix, int substitutionOffset, JavadocContext jdctx) {
-        CompilationInfo controller = jdctx.javac;
-        Element srcEl = jdctx.handle.resolve(controller);
-        Elements elements = controller.getElements();
-        Types types = controller.getTypes();
-        Trees trees = controller.getTrees();
-        TreeUtilities tu = controller.getTreeUtilities();
-        TreePath docpath = srcEl != null ? trees.getPath(srcEl) : null;
-        Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
-        for (Element e : controller.getElementUtilities().getMembers(te.asType(), null)) {
-            if ((e.getKind().isClass() || e.getKind().isInterface()) && (toExclude == null || !toExclude.contains(e))) {
-                String name = e.getSimpleName().toString();
-                    if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement)e) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types)) {
-                        items.add(JavadocCompletionItem.createTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)/*, isOfSmartType(env, e.asType(), smartTypes)*/));
-                }
-            }
-        }
-    }
-    
-    private void addPackageContent(PackageElement pe, EnumSet<ElementKind> kinds, DeclaredType baseType, Set<? extends Element> toExclude, String prefix, int substitutionOffset, JavadocContext jdctx) {
-        CompilationInfo controller = jdctx.javac;
-        Element srcEl = jdctx.handle.resolve(controller);
-        Elements elements = controller.getElements();
-        Types types = controller.getTypes();
-        Trees trees = controller.getTrees();
-        TreeUtilities tu = controller.getTreeUtilities();
-        ElementUtilities eu = controller.getElementUtilities();
-        TreePath docpath = srcEl != null ? trees.getPath(srcEl) : null;
-        Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
-        for(Element e : pe.getEnclosedElements()) {
-            if ((e.getKind().isClass() || e.getKind().isInterface()) && (toExclude == null || !toExclude.contains(e))) {
-                String name = e.getSimpleName().toString();
-                    if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e))
-                        && trees.isAccessible(scope, (TypeElement)e)
-                        && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types)
-                        && !Utilities.isExcluded(eu.getElementName(e, true))) {
-                        items.add(JavadocCompletionItem.createTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)/*, isOfSmartType(env, e.asType(), smartTypes)*/));
-                }
-            }
-        }
-    }
-        
-    private boolean isOfKindAndType(TypeMirror type, Element e, EnumSet<ElementKind> kinds, TypeMirror base, Scope scope, Trees trees, Types types) {
-        if (type.getKind() != TypeKind.ERROR && kinds.contains(e.getKind())) {
-            if (base == null)
-                return true;
-            if (types.isSubtype(type, base))
-                return true;
-        }
-        if ((e.getKind().isClass() || e.getKind().isInterface()) && 
-            (kinds.contains(ANNOTATION_TYPE) || kinds.contains(CLASS) || kinds.contains(ENUM) || kinds.contains(INTERFACE))) {
-            DeclaredType dt = (DeclaredType)e.asType();
-            for (Element ee : e.getEnclosedElements())
-                if (trees.isAccessible(scope, ee, dt) && isOfKindAndType(ee.asType(), ee, kinds, base, scope, trees, types))
-                    return true;
-        }
-        return false;
-    }
-    
-    private static boolean isAnnonInner(ElementHandle<TypeElement> elem) {
-        String name = elem.getQualifiedName();
-        int idx = name.lastIndexOf('.'); //NOI18N
-        String simpleName = idx > -1 ? name.substring(idx + 1) : name;
-        return simpleName.length() == 0 || Character.isDigit(simpleName.charAt(0));
-    }
 
-    /* copied from JavaCompletionProvider */
-    private List<DeclaredType> getSubtypesOf(DeclaredType baseType, String prefix, JavadocContext jdctx) {
-        if (((TypeElement)baseType.asElement()).getQualifiedName().contentEquals("java.lang.Object"))
-            return Collections.emptyList();
-        LinkedList<DeclaredType> subtypes = new LinkedList<DeclaredType>();
-        CompilationInfo controller = jdctx.javac;
-        Types types = controller.getTypes();
-        Trees trees = controller.getTrees();
-        TreeUtilities tu = controller.getTreeUtilities();
-        Element resolvedElm = jdctx.handle.resolve(controller);
-        TreePath docpath = resolvedElm != null ? trees.getPath(resolvedElm) : null;
-        Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
-        if (prefix != null && prefix.length() > 2 && baseType.getTypeArguments().isEmpty()) {
-            // XXX resolve camels
-//            ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
-            ClassIndex.NameKind kind = false ?
-                Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE :
-                Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
-            for(ElementHandle<TypeElement> handle : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
-                TypeElement te = handle.resolve(controller);
-                if (te != null && trees.isAccessible(scope, te) && types.isSubtype(types.getDeclaredType(te), baseType))
-                    subtypes.add(types.getDeclaredType(te));
-            }
-        } else {
-            HashSet<TypeElement> elems = new HashSet<TypeElement>();
-            LinkedList<DeclaredType> bases = new LinkedList<DeclaredType>();
-            bases.add(baseType);
-            ClassIndex index = controller.getClasspathInfo().getClassIndex();
-            while(!bases.isEmpty()) {
-                DeclaredType head = bases.remove();
-                TypeElement elem = (TypeElement)head.asElement();
-                if (!elems.add(elem))
-                    continue;
-                if (startsWith(elem.getSimpleName().toString(), prefix) && trees.isAccessible(scope, elem))
-                    subtypes.add(head);
-                List<? extends TypeMirror> tas = head.getTypeArguments();
-                boolean isRaw = !tas.iterator().hasNext();
-                subtypes:
-                for (ElementHandle<TypeElement> eh : index.getElements(ElementHandle.create(elem), EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),EnumSet.allOf(ClassIndex.SearchScope.class))) {
-                    TypeElement e = eh.resolve(controller);
-                    if (e != null) {
-                        if (trees.isAccessible(scope, e)) {
-                            if (isRaw) {
-                                DeclaredType dt = types.getDeclaredType(e);
-                                bases.add(dt);
-                            } else {
-                                HashMap<Element, TypeMirror> map = new HashMap<Element, TypeMirror>();
-                                TypeMirror sup = e.getSuperclass();
-                                if (sup.getKind() == TypeKind.DECLARED && ((DeclaredType)sup).asElement() == elem) {
-                                    DeclaredType dt = (DeclaredType)sup;
-                                    Iterator<? extends TypeMirror> ittas = tas.iterator();
-                                    Iterator<? extends TypeMirror> it = dt.getTypeArguments().iterator();
-                                    while(it.hasNext() && ittas.hasNext()) {
-                                        TypeMirror basetm = ittas.next();
-                                        TypeMirror stm = it.next();
-                                        if (basetm != stm) {
-                                            if (stm.getKind() == TypeKind.TYPEVAR) {
-                                                map.put(((TypeVariable)stm).asElement(), basetm);
-                                            } else {
-                                                continue subtypes;
-                                            }
-                                        }
-                                    }
-                                    if (it.hasNext() != ittas.hasNext()) {
-                                        continue subtypes;
-                                    }
-                                } else {
-                                    for (TypeMirror tm : e.getInterfaces()) {
-                                        if (((DeclaredType)tm).asElement() == elem) {
-                                            DeclaredType dt = (DeclaredType)tm;
-                                            Iterator<? extends TypeMirror> ittas = tas.iterator();
-                                            Iterator<? extends TypeMirror> it = dt.getTypeArguments().iterator();
-                                            while(it.hasNext() && ittas.hasNext()) {
-                                                TypeMirror basetm = ittas.next();
-                                                TypeMirror stm = it.next();
-                                                if (basetm != stm) {
-                                                    if (stm.getKind() == TypeKind.TYPEVAR) {
-                                                        map.put(((TypeVariable)stm).asElement(), basetm);
-                                                    } else {
-                                                        continue subtypes;
-                                                    }
-                                                }
-                                            }
-                                            if (it.hasNext() != ittas.hasNext()) {
-                                                continue subtypes;
-                                            }
-                                            break;
-                                        }
-                                    }
-                                }
-                                bases.add(getDeclaredType(e, map, types));
-                            }
-                        }
-                    } else {
-                        Logger.getLogger("global").log(Level.FINE, String.format("Cannot resolve: %s on bootpath: %s classpath: %s sourcepath: %s\n", eh.toString(),
-                                controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.BOOT),
-                                controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.COMPILE),
-                                controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.SOURCE)));
-                    }
-                }
-            }
-        }
-        return subtypes;
-    }
-
-    private DeclaredType getDeclaredType(TypeElement e, HashMap<? extends Element, ? extends TypeMirror> map, Types types) {
-        List<? extends TypeParameterElement> tpes = e.getTypeParameters();
-        TypeMirror[] targs = new TypeMirror[tpes.size()];
-        int i = 0;
-        for (Iterator<? extends TypeParameterElement> it = tpes.iterator(); it.hasNext();) {
-            TypeParameterElement tpe = it.next();
-            TypeMirror t = map.get(tpe);
-            targs[i++] = t != null ? t : tpe.asType();
-        }
-        Element encl = e.getEnclosingElement();
-        if ((encl.getKind().isClass() || encl.getKind().isInterface()) && !((TypeElement)encl).getTypeParameters().isEmpty())
-                return types.getDeclaredType(getDeclaredType((TypeElement)encl, map, types), e, targs);
-        return types.getDeclaredType(e, targs);
-    }
-
-    private boolean startsWith(String theString, String prefix) {
-        // XXX isCamelCasePrefix
-        return /*env.isCamelCasePrefix()*/false ? Utilities.isCaseSensitive() ? 
-            Utilities.startsWithCamelCase(theString, prefix) : 
-            Utilities.startsWithCamelCase(theString, prefix) || Utilities.startsWith(theString, prefix) :
-            Utilities.startsWith(theString, prefix);
-    }
-    
-    void resolveOtherText(JavadocContext jdctx, TokenSequence<JavadocTokenId> jdts) {
-        Token<JavadocTokenId> token = jdts.token();
-        assert token != null;
-        assert token.id() == JavadocTokenId.OTHER_TEXT;
-
-        CharSequence text = token.text();
-        int pos = caretOffset - jdts.offset();
-        DocTreePath tag = getTag(jdctx, caretOffset);
-        if (pos > 0 && pos <= text.length() && text.charAt(pos - 1) == '{') {
-            if (tag != null && !JavadocCompletionUtils.isBlockTag(tag)) {
-                int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-                if (start + 1 != caretOffset) {
-                    return;
-                }
-            }
-            resolveInlineTag(null, jdctx);
-            return;
-        }
-        
-        if (tag != null) {
-            insideTag(tag, jdctx);
-            if (JavadocCompletionUtils.isBlockTag(tag) && JavadocCompletionUtils.isLineBreak(token, pos)) {
-                resolveBlockTag(null, jdctx);
+    static List<CompletionItem> runCompletionQuery(int queryType, Document doc, int caret) {
+        JavadocCompletionTask<CompletionItem> task = JavadocCompletionTask.create(caret, new JavadocCompletionItem.Factory(),
+                queryType == CompletionProvider.COMPLETION_ALL_QUERY_TYPE, null);
+        Source source = Source.create(doc);
+        if (source != null) {
+            try {
+                ParserManager.parse(Collections.singletonList(source), task);
+            } catch (ParseException ex) {
+                Exceptions.printStackTrace(ex);
             }
-        } else if (JavadocCompletionUtils.isLineBreak(token, pos)) {
-            resolveBlockTag(null, jdctx);
         }
+        return task.getResults();
     }
-    
-    static final class JavadocContext {
-        int anchorOffset = -1;
-        ElementHandle<Element> handle;
-        Element commentFor;
-        DocCommentTree comment;
-        DocSourcePositions positions;
-        TokenSequence<JavadocTokenId> jdts;
-        Document doc;
-        CompilationInfo javac;
-        private ReferencesCount count;
-        private TreePath javadocFor;
-        ReferencesCount getReferencesCount() {
-            if (count == null)
-                count = ReferencesCount.get(javac.getClasspathInfo());
-            return count;
-        }
-    }    
 }
diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionTask.java
similarity index 56%
copy from java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java
copy to java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionTask.java
index ffc908ac16..7b5f00f569 100644
--- a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQuery.java
+++ b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionTask.java
@@ -16,27 +16,20 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.netbeans.modules.java.editor.javadoc;
 
 import com.sun.source.doctree.DocCommentTree;
 import com.sun.source.doctree.DocTree;
-import com.sun.source.doctree.DocTree.Kind;
-import com.sun.source.doctree.ErroneousTree;
 import com.sun.source.doctree.ParamTree;
 import com.sun.source.doctree.ReferenceTree;
-import com.sun.source.tree.ExpressionTree;
 import com.sun.source.tree.Scope;
 import com.sun.source.util.DocSourcePositions;
-import com.sun.source.util.DocTreeFactory;
 import com.sun.source.util.DocTreePath;
 import com.sun.source.util.DocTreePathScanner;
 import com.sun.source.util.DocTrees;
-import com.sun.source.util.SourcePositions;
 import com.sun.source.util.TreePath;
 import com.sun.source.util.Trees;
 import java.io.IOException;
-import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumSet;
@@ -46,12 +39,11 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Callable;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
-import static javax.lang.model.element.ElementKind.*;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.PackageElement;
@@ -65,10 +57,9 @@ import javax.lang.model.type.TypeMirror;
 import javax.lang.model.type.TypeVariable;
 import javax.lang.model.util.Elements;
 import javax.lang.model.util.Types;
-import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
-import javax.swing.text.JTextComponent;
-import org.netbeans.api.editor.completion.Completion;
+import org.netbeans.api.annotations.common.NonNull;
+import org.netbeans.api.annotations.common.NullAllowed;
 import org.netbeans.api.java.lexer.JavadocTokenId;
 import org.netbeans.api.java.source.ClassIndex;
 import org.netbeans.api.java.source.ClasspathInfo;
@@ -77,167 +68,84 @@ import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.api.java.source.ElementHandle;
 import org.netbeans.api.java.source.ElementUtilities;
 import org.netbeans.api.java.source.JavaSource;
-import org.netbeans.api.java.source.Task;
 import org.netbeans.api.java.source.TreeUtilities;
 import org.netbeans.api.java.source.support.ReferencesCount;
 import org.netbeans.api.lexer.Token;
 import org.netbeans.api.lexer.TokenSequence;
-import org.netbeans.modules.editor.java.JavaCompletionItem;
-import org.netbeans.modules.editor.java.LazyJavaCompletionItem;
 import org.netbeans.modules.java.completion.Utilities;
 import org.netbeans.modules.java.editor.base.javadoc.JavadocCompletionUtils;
-import org.netbeans.spi.editor.completion.CompletionItem;
-import org.netbeans.spi.editor.completion.CompletionProvider;
-import org.netbeans.spi.editor.completion.CompletionResultSet;
-import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery;
-import org.openide.util.Exceptions;
+import org.netbeans.modules.java.editor.javadoc.TagRegistery.TagEntry;
+import org.netbeans.modules.parsing.api.ResultIterator;
+import org.netbeans.modules.parsing.api.Source;
+import org.netbeans.modules.parsing.api.UserTask;
+import org.netbeans.modules.parsing.spi.Parser;
 
-/**
- *
- * @author Jan Pokorsky
- */
-final class JavadocCompletionQuery extends AsyncCompletionQuery{
-    
-    private static final String CLASS_KEYWORD = "class"; //NOI18N
-    private final int queryType;
-    
-    private int caretOffset;
-    private List<CompletionItem> items;
-    private boolean hasAdditionalItems;
-    private JTextComponent component;
-    private boolean ignoreCancel;
-    
+public class JavadocCompletionTask<T> extends UserTask {
 
-    public JavadocCompletionQuery(int queryType) {
-        this.queryType = queryType;
+    public static <I> JavadocCompletionTask<I> create(final int caretOffset, @NonNull final ItemFactory<I> factory, boolean isAllQueryType, @NullAllowed final Callable<Boolean> cancel) {
+        return new JavadocCompletionTask<>(caretOffset, factory, isAllQueryType, cancel);
     }
 
-    @Override
-    protected void prepareQuery(JTextComponent component) {
-        this.component = component;
+    public static interface ItemFactory<T> {
+        T createTagItem(String name, int startOffset);
+        T createNameItem(String name, int startOffset);
+        T createJavadocExecutableItem(CompilationInfo info, ExecutableElement e, ExecutableType et, int startOffset, boolean isInherited, boolean isDeprecated);
+        T createJavadocTypeItem(CompilationInfo info, TypeElement elem, int startOffset, boolean isDeprecated);
+        T createJavaTypeItem(CompilationInfo info, TypeElement elem, DeclaredType type, int startOffset, ReferencesCount referencesCount, boolean isDeprecated, boolean smartType);
+        T createLazyTypeItem(ElementHandle<TypeElement> handle, EnumSet<ElementKind> kinds, int startOffset, ReferencesCount referencesCount, Source source);
+        T createJavaVariableItem(CompilationInfo info, VariableElement elem, TypeMirror type, int startOffset, boolean isInherited, boolean isDeprecated);
+        T createPackageItem(String pkgFQN, int startOffset);
     }
 
-    @Override
-    protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) {
-        try {
-            queryImpl(resultSet, doc, caretOffset);
-        } catch (InterruptedException ex) {
-            Exceptions.printStackTrace(ex);
-        } catch (ExecutionException ex) {
-            Exceptions.printStackTrace(ex);
-        } finally {
-            resultSet.finish();
-        }
+    private static final Set<ElementKind> EXECUTABLE = EnumSet.of(ElementKind.METHOD, ElementKind.CONSTRUCTOR);
+    private static final String CLASS_KEYWORD = "class"; //NOI18N
+
+    private final List<T> items = new ArrayList<>();
+    private final int caretOffset;
+    private final ItemFactory<T> factory;
+    private final boolean isAllQueryType;
+    private final Callable<Boolean> cancel;
+    private int anchorOffset = -1;
+    private boolean hasAdditionalItems = false;
+
+    private JavadocCompletionTask(int caretOffset, ItemFactory<T> factory, boolean isAllQueryType, Callable<Boolean> cancel) {
+        this.caretOffset = caretOffset;
+        this.factory = factory;
+        this.isAllQueryType = isAllQueryType;
+        this.cancel = cancel;
     }
 
     @Override
-    protected boolean canFilter(JTextComponent component) {
-        final int newOffset = component.getSelectionStart();
-        final Document doc = component.getDocument();
-        if (newOffset > caretOffset && items != null && !items.isEmpty()) {
-            try {
-                String prefix = doc.getText(caretOffset, newOffset - caretOffset);
-                if (!isJavaIdentifierPart(prefix)) {
-                    Completion.get().hideDocumentation();
-                    Completion.get().hideCompletion();
-                }
-            } catch (BadLocationException ble) {
+    public void run(ResultIterator resultIterator) throws Exception {
+        Parser.Result result = resultIterator.getParserResult(caretOffset);
+        CompilationController controller = result != null ? CompilationController.get(result) : null;
+        if (controller != null && (cancel == null || !cancel.call())) {
+            if (!JavadocCompletionUtils.isJavadocContext(controller.getTokenHierarchy(), caretOffset)) {
+                return;
             }
-        }
-        return false;
-    }
-    
-    private boolean isJavaIdentifierPart(String text) {
-        for (int i = 0; i < text.length(); i++) {
-            if (!(Character.isJavaIdentifierPart(text.charAt(i))))
-                return false;
-        }
-        return true;
-    }
-
-    static List<CompletionItem> runCompletionQuery(int queryType, Document doc, int caret) {
-        JavadocCompletionQuery q = new JavadocCompletionQuery(queryType);
-        JavadocContext jdctx = new JavadocContext();
-        
-        q.items = new  ArrayList<CompletionItem>();
-        q.caretOffset = caret;
-        q.ignoreCancel = true;
-        
-        q.runInJavac(JavaSource.forDocument(doc), jdctx);
-        
-        return q.items;
-    }
-    
-    private void queryImpl(CompletionResultSet resultSet, Document doc, int caretOffset) throws InterruptedException, ExecutionException {
-        JavadocContext jdctx = new JavadocContext();
-        items = new  ArrayList<CompletionItem>();
-        this.caretOffset = caretOffset;
-        runInJavac(JavaSource.forDocument(doc), jdctx);
-        
-        if (!ignoreCancel && isTaskCancelled()) {
-            return;
-        }
-        
-        if ((queryType & CompletionProvider.COMPLETION_QUERY_TYPE) != 0) {
-            if (!items.isEmpty()) {
-                resultSet.addAllItems(items);
+            JavaSource.Phase toPhase = controller.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
+            if (toPhase != JavaSource.Phase.ELEMENTS_RESOLVED) {
+                return;
+            }
+            JavadocContext jdctx = new JavadocContext(controller);
+            if (resolveContext(controller, jdctx)) {
+                analyzeContext(jdctx);
             }
-            resultSet.setHasAdditionalItems(hasAdditionalItems);
-        }
-        
-        if (jdctx.anchorOffset >= 0) {
-            resultSet.setAnchorOffset(jdctx.anchorOffset);
         }
     }
 
-    /** #145615: this helps to work around the issue with stuck
-     * {@code JavaSource.runWhenScanFinished}
-     * It is copied from {@code JavaCompletionQuery}.
-     */
-    private void setCompletionHack(boolean flag) {
-        if (component != null) {
-            component.putClientProperty("completion-active", flag); //NOI18N
-        }
+    public List<T> getResults() {
+        return items;
     }
-    
-    private void runInJavac(JavaSource js, final JavadocContext jdctx) {
-        try {
-            if (js == null) {
-                return;
-            }
 
-            js.runUserActionTask(new Task<CompilationController>() {
+    public boolean hasAdditionalItems() {
+        return hasAdditionalItems;
+    }
 
-                public void run(CompilationController javac) throws Exception {
-                    if (!ignoreCancel && isTaskCancelled()) {
-                        return;
-                    }
-                    if (!JavadocCompletionUtils.isJavadocContext(javac.getTokenHierarchy(), caretOffset)) {
-                        return;
-                    }
-                    setCompletionHack(true);
-                    JavaSource.Phase toPhase = javac.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
-                    if (toPhase != JavaSource.Phase.ELEMENTS_RESOLVED) {
-                        return;
-                    }
-                    try {
-                        jdctx.javac = javac;
-                        if (resolveContext(javac, jdctx)) {
-                            analyzeContext(jdctx);
-                        }
-                    } finally {
-                        jdctx.javac = null;
-                        if (component != null) {
-                            setCompletionHack(false);
-                        }
-                    }
-                }
-            }, true);
-        } catch (IOException ex) {
-            Exceptions.printStackTrace(ex);
-        }
+    public int getAnchorOffset() {
+        return anchorOffset;
     }
-    
+
     private boolean resolveContext(CompilationInfo javac, JavadocContext jdctx) throws IOException {
         jdctx.doc = javac.getDocument();
         // find class context: class, method, ...
@@ -265,25 +173,22 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         jdctx.positions = (DocSourcePositions) trees.getSourcePositions();
         return jdctx.positions != null;
     }
-    
+
     private void analyzeContext(JavadocContext jdctx) {
         TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
         if (jdts == null) {
             return;
         }
-        
         jdts.move(this.caretOffset);
         if (!jdts.moveNext() && !jdts.movePrevious()) {
             // XXX solve /***/
             // provide block tags, inline tags, html
             return;
         }
-        
         if (this.caretOffset - jdts.offset() == 0) {
             // if position in token == 0 resolve CC according to previous token
             jdts.movePrevious();
         }
-        
         switch (jdts.token().id()) {
             case TAG:
                 resolveTagToken(jdctx);
@@ -309,7 +214,6 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
     void resolveTagToken(JavadocContext jdctx) {
         assert jdctx.jdts.token() != null;
         assert jdctx.jdts.token().id() == JavadocTokenId.TAG;
-
         DocTreePath tag = getTag(jdctx, caretOffset);
         if (tag == null) {
             // eg * description @
@@ -321,7 +225,7 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
             resolveInlineTag(tag, jdctx);
         }
     }
-    
+
     void resolveBlockTag(DocTreePath tag, JavadocContext jdctx) {
         int pos;
         String prefix;
@@ -332,68 +236,64 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
             prefix = ""; // NOI18N
             pos = caretOffset;
         }
-        
-        items.addAll(JavadocCompletionItem.addBlockTagItems(jdctx.handle.getKind(), prefix, pos));
-        jdctx.anchorOffset = pos;
+        addBlockTagItems(jdctx.handle.getKind(), prefix, pos);
+        anchorOffset = pos;
     }
-    
+
     void resolveInlineTag(DocTreePath tag, JavadocContext jdctx) {
         int pos;
         String prefix;
         if (tag != null) {
             pos = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf()) + 1;
             prefix = JavadocCompletionUtils.getCharSequence(jdctx.doc, pos, caretOffset).toString();
-            jdctx.anchorOffset = pos;
+            anchorOffset = pos;
         } else {
             pos = caretOffset;
             prefix = ""; // NOI18N
-            jdctx.anchorOffset = pos;
+            anchorOffset = pos;
         }
-        items.addAll(JavadocCompletionItem.addInlineTagItems(jdctx.handle.getKind(), prefix, pos));
+        addInlineTagItems(jdctx.handle.getKind(), prefix, pos);
     }
 
     private int skipWhitespacesBackwards(final JavadocContext jdctx, final int offset) {
-        jdctx.jdts.move(offset);
-        
-        while (jdctx.jdts.movePrevious()) {
+        if (jdctx.jdts.move(offset) == 0 || !jdctx.jdts.moveNext()) {
+            jdctx.jdts.movePrevious();
+        }
+        do {
             Token t = jdctx.jdts.token();
-            
-            if (t.id() != JavadocTokenId.OTHER_TEXT) return jdctx.jdts.offset();
-            
+            if (t.id() != JavadocTokenId.OTHER_TEXT) {
+                return jdctx.jdts.offset();
+            }
             CharSequence text = t.text();
-            
             for (int i = 0; i < text.length(); i++) {
                 if (!Character.isWhitespace(text.charAt(i))) {
                     //XXX: does not handle the leading '*' correctly
-                     return jdctx.jdts.offset();
+                    return jdctx.jdts.offset();
                 }
             }
-        }
-        
+        } while (jdctx.jdts.movePrevious());
         return jdctx.jdts.moveNext() ? jdctx.jdts.offset() : offset;
     }
-    
+
     private DocTreePath getTag(final JavadocContext jdctx, final int offset) {
         final DocTreePath[] result = new DocTreePath[1];
         final int normalizedOffset = skipWhitespacesBackwards(jdctx, offset);
         new DocTreePathScanner<Void, Void>() {
-            @Override public Void scan(DocTree node, Void p) {
-                if (   node != null
-                    && jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) <= normalizedOffset
-                    && jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) >= normalizedOffset) {
-                    result[0] = new DocTreePath(getCurrentPath(), node);
+            @Override
+            public Void scan(DocTree node, Void p) {
+                if (node != null && jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) <= normalizedOffset && jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, node) >= normalizedOffset) {
+                    final DocTreePath docTreePath = new DocTreePath(getCurrentPath(), node);
+                    if (JavadocCompletionUtils.isBlockTag(docTreePath) || JavadocCompletionUtils.isInlineTag(docTreePath)) {
+                        result[0] = docTreePath;
+                    }
                     return super.scan(node, p);
                 }
-                
                 return null;
             }
         }.scan(new DocTreePath(jdctx.javadocFor, jdctx.comment), null);
-        
         return result[0];
     }
-    
-    private static final Set<ElementKind> EXECUTABLE = EnumSet.of(ElementKind.METHOD, ElementKind.CONSTRUCTOR);
-    
+
     void resolveIdent(JavadocContext jdctx) {
         TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
         assert jdts.token() != null;
@@ -402,13 +302,11 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         // START -> TAG OT(WS+) MEMBER_SELECT|CLASS_SELECT
         // CLASS_SELECT -> IDENT | IDENT DOT CLASS_SELECT | IDENT MEMBER_SELECT
         // MEMBER_SELECT -> HASH IDENT OT('(')
-        
         // @see org.Clazz#meth(int p, int q)
         // TAG OT(' ') IDENT DOT IDENT HASH IDENT OT('(') IDENT OT(' ') IDENT OT(', ') IDENT OT(' ') IDENT OT(')\n...')
         // @see Clazz#meth(int p, int q)
         // @see #meth(int p, int q)
         // @see Clazz.NestedClazz
-        
         // Parenthesis content:
         // param types not neccessary to be imported or fqn!!!
         // param types may be fqn
@@ -416,56 +314,57 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         // params may contain name but they not necessary match the real names
         // param list may contain spaces
         // no space allowed between member and parenthesis
-        
         DocTreePath tag = getTag(jdctx, caretOffset);
         if (tag != null) {
             insideTag(tag, jdctx);
         }
     }
-    
+
     void resolveDotToken(JavadocContext jdctx) {
         assert jdctx.jdts.token() != null;
         assert jdctx.jdts.token().id() == JavadocTokenId.DOT;
-
         DocTreePath tag = getTag(jdctx, caretOffset);
         if (tag != null) {
             insideTag(tag, jdctx);
         }
     }
-    
+
     void resolveHashToken(JavadocContext jdctx) {
         assert jdctx.jdts.token() != null;
         assert jdctx.jdts.token().id() == JavadocTokenId.HASH;
-
         DocTreePath tag = getTag(jdctx, caretOffset);
         if (tag != null) {
             insideTag(tag, jdctx);
         }
     }
-    
+
     void resolveHTMLToken(JavadocContext jdctx) {
         assert jdctx.jdts.token() != null;
         assert jdctx.jdts.token().id() == JavadocTokenId.HTML_TAG;
-
         DocTreePath tag = getTag(jdctx, caretOffset);
-        if (tag != null && tag.getLeaf().getKind() == Kind.PARAM) {
+        if (tag != null && JavadocCompletionUtils.normalizedKind(tag.getLeaf()) == DocTree.Kind.PARAM) {
             // type param
             insideParamTag(tag, jdctx);
         }
     }
-    
+
     private void insideTag(DocTreePath tag, JavadocContext jdctx) {
         switch (JavadocCompletionUtils.normalizedKind(tag.getLeaf())) {
             case IDENTIFIER:
-                if (tag.getParentPath() == null || tag.getParentPath().getLeaf().getKind() != Kind.PARAM)
+                if (tag.getParentPath() == null || tag.getParentPath().getLeaf().getKind() != DocTree.Kind.PARAM) {
                     break;
+                }
                 tag = tag.getParentPath();
-                //intentional fall-through:
+        //intentional fall-through:
             case PARAM:
                 insideParamTag(tag, jdctx);
                 break;
-            case SEE: case THROWS: case VALUE:
-            case LINK: case LINK_PLAIN://XXX: was only unclosed???
+            case SEE:
+            case THROWS:
+            case VALUE:
+            case LINK:
+            case LINK_PLAIN:
+                //XXX: was only unclosed???
                 insideSeeTag(tag, jdctx);
                 break;
             case REFERENCE:
@@ -473,19 +372,17 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                 break;
         }
     }
-    
+
     private void insideSeeTag(DocTreePath tag, JavadocContext jdctx) {
         TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
         assert jdts.token() != null;
         int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-        
-        boolean isThrowsKind = JavadocCompletionUtils.normalizedKind(tag.getLeaf()) == Kind.THROWS;
+        boolean isThrowsKind = JavadocCompletionUtils.normalizedKind(tag.getLeaf()) == DocTree.Kind.THROWS;
         if (isThrowsKind && !(EXECUTABLE.contains(jdctx.commentFor.getKind()))) {
             // illegal tag in this context
             return;
         }
-        
-        jdts.move(start + (JavadocCompletionUtils.isBlockTag(tag)? 0: 1));
+        jdts.move(start + (JavadocCompletionUtils.isBlockTag(tag) ? 0 : 1));
         // @see|@link|@throws
         if (!jdts.moveNext() || caretOffset <= jdts.offset() + jdts.token().length()) {
             return;
@@ -494,53 +391,44 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         if (!jdts.moveNext() || caretOffset <= jdts.offset()) {
             return;
         }
-        
         boolean noPrefix = false;
-        
         if (caretOffset <= jdts.offset() + jdts.token().length()) {
             int pos = caretOffset - jdts.offset();
             CharSequence cs = jdts.token().text();
-            cs = pos < cs.length()? cs.subSequence(0, pos): cs;
-            
-            if (JavadocCompletionUtils.isWhiteSpace(cs)
-                    || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
+            cs = pos < cs.length() ? cs.subSequence(0, pos) : cs;
+            if (JavadocCompletionUtils.isWhiteSpace(cs) || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
                 noPrefix = true;
             } else {
                 // broken syntax
                 return;
             }
-        } else if (! (JavadocCompletionUtils.isWhiteSpace(jdts.token())
-                || JavadocCompletionUtils.isLineBreak(jdts.token()) )) {
+        } else if (!(JavadocCompletionUtils.isWhiteSpace(jdts.token()) || JavadocCompletionUtils.isLineBreak(jdts.token()))) {
             // not java reference
             return;
         } else if (jdts.moveNext()) {
             int end = (int) jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
             insideReference(JavadocCompletionUtils.normalizedKind(tag.getLeaf()), jdts.offset(), end, jdctx);
         }
-        
         if (noPrefix) {
             // complete all types + members
-            
             if (isThrowsKind) {
                 completeThrowsOrPkg(null, "", caretOffset, jdctx); // NOI18N
             } else {
                 completeClassOrPkg(null, "", caretOffset, jdctx); // NOI18N
             }
-            jdctx.anchorOffset = caretOffset;
-            return;
+            anchorOffset = caretOffset;
         }
     }
-    
+
     private void insideReference(DocTreePath tag, JavadocContext jdctx) {
         ReferenceTree ref = (ReferenceTree) tag.getLeaf();
-        Kind kind = tag.getParentPath().getLeaf().getKind();
+        DocTree.Kind kind = tag.getParentPath().getLeaf().getKind();
         int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, ref);
-        int end   = (int) jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, ref);
-
+        int end = (int) jdctx.positions.getEndPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, ref);
         insideReference(kind, start, end, jdctx);
     }
 
-    private void insideReference(Kind enclosingKind, int start, int end, JavadocContext jdctx) {
+    private void insideReference(DocTree.Kind enclosingKind, int start, int end, JavadocContext jdctx) {
         // complete type
         CharSequence cs = JavadocCompletionUtils.getCharSequence(jdctx.doc, start, end);
         StringBuilder sb = new StringBuilder();
@@ -550,24 +438,20 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                 // complete class member
                 String prefix = sb.toString();
                 int substitutionOffset = caretOffset - sb.length();
-                jdctx.anchorOffset = substitutionOffset;
+                anchorOffset = substitutionOffset;
                 if (i == 0) {
-                    if (enclosingKind == Kind.VALUE) {
+                    if (enclosingKind == DocTree.Kind.VALUE) {
                         addLocalConstants(jdctx, prefix, substitutionOffset);
                     } else {
                         addLocalMembersAndVars(jdctx, prefix, substitutionOffset);
                     }
                 } else {
-                    TypeElement scopeType = jdctx.commentFor.getKind().isClass() || jdctx.commentFor.getKind().isInterface() ? (TypeElement) jdctx.commentFor
-                                                                                                                             : jdctx.javac.getElementUtilities().enclosingTypeElement(jdctx.commentFor);
-                    TypeMirror type = 
-                            jdctx.javac.getTreeUtilities().parseType(cs.subSequence(0, i).toString(), scopeType);
-                    if (enclosingKind == Kind.VALUE) {
+                    TypeElement scopeType = jdctx.commentFor.getKind().isClass() || jdctx.commentFor.getKind().isInterface() ? (TypeElement) jdctx.commentFor : jdctx.javac.getElementUtilities().enclosingTypeElement(jdctx.commentFor);
+                    TypeMirror type = jdctx.javac.getTreeUtilities().parseType(cs.subSequence(0, i).toString(), scopeType);
+                    if (enclosingKind == DocTree.Kind.VALUE) {
                         addMemberConstants(jdctx, prefix, substitutionOffset, type);
                     } else {
-                        addMembers(jdctx, prefix, substitutionOffset, type, jdctx.javac.getTypes().asElement(type),
-                                EnumSet.<ElementKind>of(ENUM_CONSTANT, FIELD, METHOD, CONSTRUCTOR),
-                                null);
+                        addMembers(jdctx, prefix, substitutionOffset, type, jdctx.javac.getTypes().asElement(type), EnumSet.<ElementKind>of(ElementKind.ENUM_CONSTANT, ElementKind.FIELD, ElementKind.METHOD, ElementKind.CONSTRUCTOR), null);
                     }
                 }
                 return;
@@ -576,8 +460,8 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                 String prefix = sb.toString();
                 String fqn = cs.subSequence(0, i).toString();
                 int substitutionOffset = caretOffset - sb.length();
-                jdctx.anchorOffset = substitutionOffset;
-                if (enclosingKind == Kind.THROWS) {
+                anchorOffset = substitutionOffset;
+                if (enclosingKind == DocTree.Kind.THROWS) {
                     completeThrowsOrPkg(fqn, prefix, substitutionOffset, jdctx);
                 } else {
                     completeClassOrPkg(fqn, prefix, substitutionOffset, jdctx);
@@ -591,19 +475,18 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         String prefix = sb.toString();
         String fqn = null;
         int substitutionOffset = caretOffset - sb.length();
-        jdctx.anchorOffset = substitutionOffset;
-        if (enclosingKind == Kind.THROWS) {
+        anchorOffset = substitutionOffset;
+        if (enclosingKind == DocTree.Kind.THROWS) {
             completeThrowsOrPkg(fqn, prefix, substitutionOffset, jdctx);
         } else {
             completeClassOrPkg(fqn, prefix, substitutionOffset, jdctx);
         }
     }
-    
+
     private void insideParamTag(DocTreePath tag, JavadocContext jdctx) {
         TokenSequence<JavadocTokenId> jdts = jdctx.jdts;
         assert jdts.token() != null;
         int start = (int) jdctx.positions.getStartPosition(jdctx.javac.getCompilationUnit(), jdctx.comment, tag.getLeaf());
-        
         jdts.move(start);
         // @param
         if (!jdts.moveNext() || caretOffset <= jdts.offset() + jdts.token().length()) {
@@ -613,16 +496,13 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         if (!jdts.moveNext() || caretOffset <= jdts.offset()) {
             return;
         }
-        
         if (caretOffset <= jdts.offset() + jdts.token().length()) {
             int pos = caretOffset - jdts.offset();
             CharSequence cs = jdts.token().text();
-            cs = pos < cs.length()? cs.subSequence(0, pos): cs;
-            
-            if (JavadocCompletionUtils.isWhiteSpace(cs)
-                    || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
+            cs = pos < cs.length() ? cs.subSequence(0, pos) : cs;
+            if (JavadocCompletionUtils.isWhiteSpace(cs) || JavadocCompletionUtils.isLineBreak(jdts.token(), pos)) {
                 // none prefix
-                jdctx.anchorOffset = caretOffset;
+                anchorOffset = caretOffset;
                 completeParamName(tag, "", caretOffset, jdctx); // NOI18N
                 return;
             } else {
@@ -630,7 +510,6 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                 return;
             }
         }
-        
         jdts.moveNext(); // param name
         if (!(jdts.token().id() == JavadocTokenId.IDENT || jdts.token().id() == JavadocTokenId.HTML_TAG)) {
             // broken syntax
@@ -638,24 +517,21 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         }
         if (caretOffset <= jdts.offset() + jdts.token().length()) {
             CharSequence prefix = jdts.token().text().subSequence(0, caretOffset - jdts.offset());
-            jdctx.anchorOffset = jdts.offset();
+            anchorOffset = jdts.offset();
             completeParamName(tag, prefix.toString(), jdts.offset(), jdctx);
-            return;
         }
     }
-    
+
     private void completeParamName(DocTreePath tag, String prefix, int substitutionOffset, JavadocContext jdctx) {
         if (EXECUTABLE.contains(jdctx.commentFor.getKind())) {
             List<? extends DocTree> blockTags = jdctx.comment.getBlockTags();
             ExecutableElement method = (ExecutableElement) jdctx.commentFor;
             for (VariableElement param : method.getParameters()) {
                 String name = param.getSimpleName().toString();
-
                 if (!containsParam(blockTags, name) && name.startsWith(prefix)) {
-                    items.add(JavadocCompletionItem.createNameItem(name, substitutionOffset));
+                    items.add(factory.createNameItem(name, substitutionOffset));
                 }
             }
-            
             completeTypeVarName(jdctx.commentFor, prefix, substitutionOffset);
         } else if (jdctx.commentFor.getKind().isClass() || jdctx.commentFor.getKind().isInterface()) {
             completeTypeVarName(jdctx.commentFor, prefix, substitutionOffset);
@@ -664,9 +540,9 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
 
     private boolean containsParam(List<? extends DocTree> blockTags, String name) {
         for (DocTree blockTag : blockTags) {
-            if(blockTag.getKind() == Kind.PARAM) {
+            if (blockTag.getKind() == DocTree.Kind.PARAM) {
                 ParamTree param = (ParamTree) blockTag;
-                if(name.contentEquals(param.getName().getName())) {
+                if (name.contentEquals(param.getName().getName())) {
                     return true;
                 }
             }
@@ -683,58 +559,49 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                 return;
             }
         }
-        List<? extends TypeParameterElement> tparams = (forElement.getKind().isClass() || forElement.getKind().isInterface())
-             ? ((TypeElement) forElement).getTypeParameters()
-             : ((ExecutableElement) forElement).getTypeParameters();
-        
+        List<? extends TypeParameterElement> tparams = (forElement.getKind().isClass() || forElement.getKind().isInterface()) ? ((TypeElement) forElement).getTypeParameters() : ((ExecutableElement) forElement).getTypeParameters();
         for (TypeParameterElement typeVariable : tparams) {
             String name = typeVariable.getSimpleName().toString();
             if (name.startsWith(prefix)) {
-                items.add(JavadocCompletionItem.createNameItem(
-                        '<' + name + '>', substitutionOffset));
+                items.add(factory.createNameItem('<' + name + '>', substitutionOffset));
             }
         }
     }
-    
+
     private void completeClassOrPkg(String fqn, String prefix, int substitutionOffset, JavadocContext jdctx) {
         String pkgPrefix;
         if (fqn == null) {
             pkgPrefix = prefix;
-            addTypes(EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
-                    null, null, prefix, substitutionOffset, jdctx);
-            
+            addTypes(EnumSet.<ElementKind>of(ElementKind.CLASS, ElementKind.INTERFACE, ElementKind.ENUM, ElementKind.ANNOTATION_TYPE), null, null, prefix, substitutionOffset, jdctx);
         } else {
             pkgPrefix = fqn + '.' + prefix;
             PackageElement pkgElm = jdctx.javac.getElements().getPackageElement(fqn);
             if (pkgElm != null) {
-                addPackageContent(pkgElm,
-                        EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
-                        null, null, prefix, substitutionOffset, jdctx);
+                addPackageContent(pkgElm, EnumSet.<ElementKind>of(ElementKind.CLASS, ElementKind.INTERFACE, ElementKind.ENUM, ElementKind.ANNOTATION_TYPE), null, null, prefix, substitutionOffset, jdctx);
             }
-            
             TypeElement typeElm = jdctx.javac.getElements().getTypeElement(fqn);
             if (typeElm != null) {
                 // inner classes
-                addInnerClasses(typeElm,
-                        EnumSet.<ElementKind>of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE),
-                        null, null, prefix, substitutionOffset, jdctx);
+                addInnerClasses(typeElm, EnumSet.<ElementKind>of(ElementKind.CLASS, ElementKind.INTERFACE, ElementKind.ENUM, ElementKind.ANNOTATION_TYPE), null, null, prefix, substitutionOffset, jdctx);
+            }
+        }
+        for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class))) {
+            if (pkgName.length() > 0 && !Utilities.isExcluded(pkgName + ".")) {
+                items.add(factory.createPackageItem(pkgName, substitutionOffset));
             }
         }
-        
-        for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class)))
-            if (pkgName.length() > 0 && !Utilities.isExcluded(pkgName + "."))
-                items.add(JavaCompletionItem.createPackageItem(pkgName, substitutionOffset, false));
     }
-    
+
     private void completeThrowsOrPkg(String fqn, String prefix, int substitutionOffset, JavadocContext jdctx) {
         final Elements elements = jdctx.javac.getElements();
         final Set<Element> excludes = new HashSet<Element>();
         String pkgPrefix;
-        
-        // add declared Throwables        
+        // add declared Throwables
         ExecutableElement method = (ExecutableElement) jdctx.commentFor;
         for (TypeMirror type : method.getThrownTypes()) {
-            if (type.getKind() != TypeKind.DECLARED) continue;
+            if (type.getKind() != TypeKind.DECLARED) {
+                continue;
+            }
             TypeElement clazz = (TypeElement) ((DeclaredType) type).asElement();
             String typeName = clazz.getSimpleName().toString();
             if (startsWith(typeName, prefix)) {
@@ -743,51 +610,38 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                 if (typeElement == null) {
                     continue;
                 }
-                items.add(JavaCompletionItem.createTypeItem(
-                        jdctx.javac, typeElement, (DeclaredType) typeElement.asType(),
-                        substitutionOffset, /*XXX:*/typeName != qualTypeName ? jdctx.getReferencesCount() : null,
-                        elements.isDeprecated(typeElement), false, false, false, true, false, null));
+                items.add(factory.createJavaTypeItem(jdctx.javac, typeElement, (DeclaredType) typeElement.asType(), substitutionOffset, /*XXX:*/ typeName != qualTypeName ? jdctx.getReferencesCount() : null, elements.isDeprecated(typeElement), true));
                 excludes.add(typeElement);
             }
         }
-
-        // add other Throwables        
+        // add other Throwables
         if (fqn == null) {
             pkgPrefix = prefix;
-            addTypes(EnumSet.<ElementKind>of(CLASS),
-                    findDeclaredType("java.lang.Throwable", elements), // NOI18N
-                    excludes, prefix, substitutionOffset, jdctx);
-            
+            addTypes(EnumSet.<ElementKind>of(ElementKind.CLASS), findDeclaredType("java.lang.Throwable", elements), // NOI18N
+            excludes, prefix, substitutionOffset, jdctx);
         } else {
             pkgPrefix = fqn + '.' + prefix;
-            
             PackageElement pkgElm = elements.getPackageElement(fqn);
             if (pkgElm != null) {
-                addPackageContent(pkgElm,
-                        EnumSet.<ElementKind>of(CLASS),
-                        findDeclaredType("java.lang.Throwable", elements), // NOI18N
-                        excludes, prefix, substitutionOffset, jdctx);
+                addPackageContent(pkgElm, EnumSet.<ElementKind>of(ElementKind.CLASS), findDeclaredType("java.lang.Throwable", elements), // NOI18N
+                excludes, prefix, substitutionOffset, jdctx);
             }
-            
             TypeElement typeElm = elements.getTypeElement(fqn);
             if (typeElm != null) {
                 // inner classes
-                addInnerClasses(typeElm,
-                        EnumSet.<ElementKind>of(CLASS),
-                        findDeclaredType("java.lang.Throwable", elements), // NOI18N
-                        excludes, prefix, substitutionOffset, jdctx);
+                addInnerClasses(typeElm, EnumSet.<ElementKind>of(ElementKind.CLASS), findDeclaredType("java.lang.Throwable", elements), // NOI18N
+                excludes, prefix, substitutionOffset, jdctx);
             }
         }
-        
-        
         // add packages
-        
-        for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class)))
-            if (pkgName.length() > 0)
-                items.add(JavaCompletionItem.createPackageItem(pkgName, substitutionOffset, false));
+        for (String pkgName : jdctx.javac.getClasspathInfo().getClassIndex().getPackageNames(pkgPrefix, true, EnumSet.allOf(ClassIndex.SearchScope.class))) {
+            if (pkgName.length() > 0) {
+                items.add(factory.createPackageItem(pkgName, substitutionOffset));
+            }
+        }
     }
-    
-    private static DeclaredType findDeclaredType(CharSequence fqn, Elements elements) {
+
+    private DeclaredType findDeclaredType(CharSequence fqn, Elements elements) {
         TypeElement re = elements.getTypeElement(fqn);
         if (re != null) {
             TypeMirror asType = re.asType();
@@ -797,88 +651,100 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         }
         return null;
     }
-    
+
+    private void addBlockTagItems(ElementKind kind, String prefix, int startOffset) {
+        List<TagEntry> tags = TagRegistery.getDefault().getTags(kind, false);
+        for (TagEntry tagEntry : tags) {
+            if (tagEntry.name.startsWith(prefix)) {
+                items.add(factory.createTagItem(tagEntry.name, startOffset));
+            }
+        }
+    }
+
+    private void addInlineTagItems(ElementKind kind, String prefix, int startOffset) {
+        List<TagEntry> tags = TagRegistery.getDefault().getTags(kind, true);
+        for (TagEntry tagEntry : tags) {
+            if (tagEntry.name.startsWith(prefix)) {
+                items.add(factory.createTagItem(tagEntry.name, startOffset));
+            }
+        }
+    }
+
     private void addMembers(final JavadocContext env, final String prefix, final int substitutionOffset, final TypeMirror type, final Element elem, final EnumSet<ElementKind> kinds, final DeclaredType baseType) {
-        Set<? extends TypeMirror> smartTypes = /*queryType == COMPLETION_QUERY_TYPE ? env.getSmartTypes() :*/ null;
+        //        Set<? extends TypeMirror> smartTypes = /*queryType == COMPLETION_QUERY_TYPE ? env.getSmartTypes() :*/ null;
         final CompilationInfo controller = env.javac;
         final Trees trees = controller.getTrees();
         final Elements elements = controller.getElements();
         final Types types = controller.getTypes();
         final TreeUtilities tu = controller.getTreeUtilities();
         final ElementUtilities eu = controller.getElementUtilities();
-        TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement)((DeclaredType)type).asElement() : null;
-//        final boolean isStatic = elem != null && (elem.getKind().isClass() || elem.getKind().isInterface() || elem.getKind() == TYPE_PARAMETER);
-//        final boolean isSuperCall = elem != null && elem.getKind().isField() && elem.getSimpleName().contentEquals(SUPER_KEYWORD);
+        TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement) ((DeclaredType) type).asElement() : null;
+        //        final boolean isStatic = elem != null && (elem.getKind().isClass() || elem.getKind().isInterface() || elem.getKind() == TYPE_PARAMETER);
+        //        final boolean isSuperCall = elem != null && elem.getKind().isField() && elem.getSimpleName().contentEquals(SUPER_KEYWORD);
         Element docelm = env.handle.resolve(controller);
         TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
         final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
         TypeElement enclClass = scope.getEnclosingClass();
-        final TypeMirror enclType = enclClass != null ? enclClass.asType() : null;
+        //        final TypeMirror enclType = enclClass != null ? enclClass.asType() : null;
         ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
             public boolean accept(Element e, TypeMirror t) {
                 switch (e.getKind()) {
                     case FIELD:
                         String name = e.getSimpleName().toString();
-                        return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
-                                &&  (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
-//                                &&
-//                                isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
-//                                tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t) && 
-//                                (!isStatic || e.getModifiers().contains(Modifier.STATIC)) &&
-//                                (isStatic || !e.getSimpleName().contentEquals(THIS_KEYWORD)) &&
-//                                ((isStatic && !inImport) /*|| !e.getSimpleName().contentEquals(CLASS_KEYWORD)*/);
+                        return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
+                //                                &&
+                //                                isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
+                //                                tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t) &&
+                //                                (!isStatic || e.getModifiers().contains(Modifier.STATIC)) &&
+                //                                (isStatic || !e.getSimpleName().contentEquals(THIS_KEYWORD)) &&
+                //                                ((isStatic && !inImport) /*|| !e.getSimpleName().contentEquals(CLASS_KEYWORD)*/);
                     case ENUM_CONSTANT:
-                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-//                                isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
+                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && //                                isOfKindAndType(asMemberOf(e, t, types), e, kinds, baseType, scope, trees, types) &&
+                        trees.isAccessible(scope, e, (DeclaredType) t);
                     case METHOD:
                         String sn = e.getSimpleName().toString();
-                        return Utilities.startsWith(sn, prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-                                (!Utilities.isExcludeMethods() || !Utilities.isExcluded(eu.getElementName(e.getEnclosingElement(), true) + "." + sn)); //NOI18N
-//                                &&
-//                                isOfKindAndType(((ExecutableType)asMemberOf(e, t, types)).getReturnType(), e, kinds, baseType, scope, trees, types) &&
-//                                (isSuperCall && e.getModifiers().contains(PROTECTED) || tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t)) &&
-//                                (!isStatic || e.getModifiers().contains(Modifier.STATIC));
-//                    case CLASS:
-//                    case ENUM:
-//                    case INTERFACE:
-//                    case ANNOTATION_TYPE:
-//                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-//                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-//                                isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types) &&
-//                                tu.isAccessible(scope, e, t) && isStatic;
+                        return Utilities.startsWith(sn, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && (!Utilities.isExcludeMethods() || !Utilities.isExcluded(eu.getElementName(e.getEnclosingElement(), true) + "." + sn)); //NOI18N
+                //                                &&
+                //                                isOfKindAndType(((ExecutableType)asMemberOf(e, t, types)).getReturnType(), e, kinds, baseType, scope, trees, types) &&
+                //                                (isSuperCall && e.getModifiers().contains(PROTECTED) || tu.isAccessible(scope, e, isSuperCall && enclType != null ? enclType : t)) &&
+                //                                (!isStatic || e.getModifiers().contains(Modifier.STATIC));
+                //                    case CLASS:
+                //                    case ENUM:
+                //                    case INTERFACE:
+                //                    case ANNOTATION_TYPE:
+                //                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
+                //                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
+                //                                isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types) &&
+                //                                tu.isAccessible(scope, e, t) && isStatic;
                     case CONSTRUCTOR:
-                        return (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-//                                isOfKindAndType(e.getEnclosingElement().asType(), e, kinds, baseType, scope, trees, types) &&
-                                (trees.isAccessible(scope, e, (DeclaredType)t) || (elem.getModifiers().contains(Modifier.ABSTRACT) && !e.getModifiers().contains(Modifier.PRIVATE)));
-//                                &&
-//                                isStatic;
+                        return (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && //                                isOfKindAndType(e.getEnclosingElement().asType(), e, kinds, baseType, scope, trees, types) &&
+                        (trees.isAccessible(scope, e, (DeclaredType) t) || (elem.getModifiers().contains(Modifier.ABSTRACT) && !e.getModifiers().contains(Modifier.PRIVATE)));
+                        //                                &&
+                        //                                isStatic;
                 }
                 return false;
             }
         };
-        for(Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
+        for (Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
             switch (e.getKind()) {
                 case ENUM_CONSTANT:
                 case FIELD:
-                    TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType();
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement) e, tm, null, substitutionOffset, null, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), /*isOfSmartType(env, tm, smartTypes)*/false, -1, null));
+                    TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType) type, e) : e.asType();
+                    items.add(factory.createJavaVariableItem(controller, (VariableElement) e, tm, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e)));
                     break;
                 case CONSTRUCTOR:
                 case METHOD:
-                    ExecutableType et = (ExecutableType)(type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType());
-//                    items.add(JavaCompletionItem.createExecutableItem((ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), inImport, /*isOfSmartType(env, et.getReturnType(), smartTypes)*/false));
-                    items.add(JavadocCompletionItem.createExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e)));
+                    ExecutableType et = (ExecutableType) (type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType) type, e) : e.asType());
+                    //                    items.add(JavaCompletionItem.createExecutableItem((ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), inImport, /*isOfSmartType(env, et.getReturnType(), smartTypes)*/false));
+                    items.add(factory.createJavadocExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e)));
                     break;
-//                case CLASS:
-//                case ENUM:
-//                case INTERFACE:
-//                case ANNOTATION_TYPE:
-//                    DeclaredType dt = (DeclaredType)(type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType());
-//                    results.add(JavaCompletionItem.createTypeItem((TypeElement)e, dt, anchorOffset, false, elements.isDeprecated(e), insideNew, false));
-//                    break;
+                    //                case CLASS:
+                    //                case ENUM:
+                    //                case INTERFACE:
+                    //                case ANNOTATION_TYPE:
+                    //                    DeclaredType dt = (DeclaredType)(type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType());
+                    //                    results.add(JavaCompletionItem.createTypeItem((TypeElement)e, dt, anchorOffset, false, elements.isDeprecated(e), insideNew, false));
+                    //                    break;
             }
         }
     }
@@ -889,7 +755,7 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         final Elements elements = controller.getElements();
         final Types types = controller.getTypes();
         final TreeUtilities tu = controller.getTreeUtilities();
-        TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement)((DeclaredType)type).asElement() : null;
+        TypeElement typeElem = type.getKind() == TypeKind.DECLARED ? (TypeElement) ((DeclaredType) type).asElement() : null;
         Element docelm = env.handle.resolve(controller);
         TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
         final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
@@ -898,24 +764,19 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                 switch (e.getKind()) {
                     case FIELD:
                         String name = e.getSimpleName().toString();
-                        return ((VariableElement)e).getConstantValue() != null
-                                && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
-                                && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
+                        return ((VariableElement) e).getConstantValue() != null && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
                     case ENUM_CONSTANT:
-                        return ((VariableElement)e).getConstantValue() != null &&
-                                Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
+                        return ((VariableElement) e).getConstantValue() != null && Utilities.startsWith(e.getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, e, (DeclaredType) t);
                 }
                 return false;
             }
         };
-        for(Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
+        for (Element e : controller.getElementUtilities().getMembers(type, acceptor)) {
             switch (e.getKind()) {
                 case ENUM_CONSTANT:
                 case FIELD:
-                    TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType)type, e) : e.asType();
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement) e, tm, null, substitutionOffset, null, typeElem != e.getEnclosingElement(), elements.isDeprecated(e), /*isOfSmartType(env, tm, smartTypes)*/false, -1, null));
+                    TypeMirror tm = type.getKind() == TypeKind.DECLARED ? types.asMemberOf((DeclaredType) type, e) : e.asType();
+                    items.add(factory.createJavaVariableItem(controller, (VariableElement) e, tm, substitutionOffset, typeElem != e.getEnclosingElement(), elements.isDeprecated(e)));
                     break;
             }
         }
@@ -936,14 +797,9 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                 switch (e.getKind()) {
                     case FIELD:
                         String name = e.getSimpleName().toString();
-                        return ((VariableElement)e).getConstantValue() != null
-                                && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
-                                &&  (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
+                        return ((VariableElement) e).getConstantValue() != null && Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
                     case ENUM_CONSTANT:
-                        return ((VariableElement)e).getConstantValue() != null &&
-                                Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
+                        return ((VariableElement) e).getConstantValue() != null && Utilities.startsWith(e.getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, e, (DeclaredType) t);
                 }
                 return false;
             }
@@ -951,11 +807,11 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         for (Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
             switch (e.getKind()) {
                 case ENUM_CONSTANT:
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, e.asType(), null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, e.asType(), smartTypes)*/, -1, null));
+                    items.add(factory.createJavaVariableItem(controller, (VariableElement) e, e.asType(), substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
                     break;
                 case FIELD:
                     TypeMirror tm = asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, tm, null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, tm, smartTypes)*/, -1, null));
+                    items.add(factory.createJavaVariableItem(controller, (VariableElement) e, tm, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
                     break;
             }
         }
@@ -970,77 +826,70 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         Element docelm = env.handle.resolve(controller);
         TreePath docpath = docelm != null ? trees.getPath(docelm) : null;
         final Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
-        Set<? extends TypeMirror> smartTypes = null;
-//        if (queryType == COMPLETION_QUERY_TYPE) {
-//            smartTypes = env.getSmartTypes();
-//            if (smartTypes != null) {
-//                for (TypeMirror st : smartTypes) {
-//                    if (st.getKind().isPrimitive())
-//                        st = types.boxedClass((PrimitiveType)st).asType();
-//                    if (st.getKind() == TypeKind.DECLARED) {
-//                        final DeclaredType type = (DeclaredType)st;
-//                        final TypeElement element = (TypeElement)type.asElement();
-//                        if (withinScope(env, element))
-//                            continue;
-//                        final boolean isStatic = element.getKind().isClass() || element.getKind().isInterface();
-//                        final Set<? extends TypeMirror> finalSmartTypes = smartTypes;
-//                        ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
-//                            public boolean accept(Element e, TypeMirror t) {
-//                                return (!isStatic || e.getModifiers().contains(STATIC)) &&
-//                                        Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-//                                        tu.isAccessible(scope, e, t) &&
-//                                        (e.getKind().isField() && isOfSmartType(env, ((VariableElement)e).asType(), finalSmartTypes) || e.getKind() == METHOD && isOfSmartType(env, ((ExecutableElement)e).getReturnType(), finalSmartTypes));
-//                            }
-//                        };
-//                        for (Element ee : controller.getElementUtilities().getMembers(type, acceptor)) {
-//                            if (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(ee))
-//                                results.add(JavaCompletionItem.createStaticMemberItem(type, ee, types.asMemberOf(type, ee), anchorOffset, elements.isDeprecated(ee)));
-//                        }
-//                    }
-//                }
-//            }
-//        }
+        //        Set<? extends TypeMirror> smartTypes = null;
+        //        if (queryType == COMPLETION_QUERY_TYPE) {
+        //            smartTypes = env.getSmartTypes();
+        //            if (smartTypes != null) {
+        //                for (TypeMirror st : smartTypes) {
+        //                    if (st.getKind().isPrimitive())
+        //                        st = types.boxedClass((PrimitiveType)st).asType();
+        //                    if (st.getKind() == TypeKind.DECLARED) {
+        //                        final DeclaredType type = (DeclaredType)st;
+        //                        final TypeElement element = (TypeElement)type.asElement();
+        //                        if (withinScope(env, element))
+        //                            continue;
+        //                        final boolean isStatic = element.getKind().isClass() || element.getKind().isInterface();
+        //                        final Set<? extends TypeMirror> finalSmartTypes = smartTypes;
+        //                        ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
+        //                            public boolean accept(Element e, TypeMirror t) {
+        //                                return (!isStatic || e.getModifiers().contains(STATIC)) &&
+        //                                        Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
+        //                                        tu.isAccessible(scope, e, t) &&
+        //                                        (e.getKind().isField() && isOfSmartType(env, ((VariableElement)e).asType(), finalSmartTypes) || e.getKind() == METHOD && isOfSmartType(env, ((ExecutableElement)e).getReturnType(), finalSmartTypes));
+        //                            }
+        //                        };
+        //                        for (Element ee : controller.getElementUtilities().getMembers(type, acceptor)) {
+        //                            if (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(ee))
+        //                                results.add(JavaCompletionItem.createStaticMemberItem(type, ee, types.asMemberOf(type, ee), anchorOffset, elements.isDeprecated(ee)));
+        //                        }
+        //                    }
+        //                }
+        //            }
+        //        }
         final TypeElement enclClass = scope.getEnclosingClass();
-//        final boolean isStatic = enclClass == null ? false :
-//            (tu.isStaticContext(scope) || (env.getPath().getLeaf().getKind() == Tree.Kind.BLOCK && ((BlockTree)env.getPath().getLeaf()).isStatic()));
-//        final Collection<? extends Element> illegalForwardRefs = env.getForwardReferences();
-        final ExecutableElement method = scope.getEnclosingMethod();
+        //        final boolean isStatic = enclClass == null ? false :
+        //            (tu.isStaticContext(scope) || (env.getPath().getLeaf().getKind() == Tree.Kind.BLOCK && ((BlockTree)env.getPath().getLeaf()).isStatic()));
+        //        final Collection<? extends Element> illegalForwardRefs = env.getForwardReferences();
+        //        final ExecutableElement method = scope.getEnclosingMethod();
         ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
             public boolean accept(Element e, TypeMirror t) {
                 switch (e.getKind()) {
                     case CONSTRUCTOR:
-                        return Utilities.startsWith(e.getEnclosingElement().getSimpleName().toString(), prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-//                                (!isStatic || e.getModifiers().contains(STATIC)) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
-//                    case LOCAL_VARIABLE:
-//                    case EXCEPTION_PARAMETER:
-//                    case PARAMETER:
-//                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-//                                (method == e.getEnclosingElement() || e.getModifiers().contains(FINAL) ||
-//                                (method == null && (e.getEnclosingElement().getKind() == INSTANCE_INIT ||
-//                                e.getEnclosingElement().getKind() == STATIC_INIT))) &&
-//                                !illegalForwardRefs.contains(e);
+                        return Utilities.startsWith(e.getEnclosingElement().getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && //                                (!isStatic || e.getModifiers().contains(STATIC)) &&
+                        trees.isAccessible(scope, e, (DeclaredType) t);
+                //                    case LOCAL_VARIABLE:
+                //                    case EXCEPTION_PARAMETER:
+                //                    case PARAMETER:
+                //                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
+                //                                (method == e.getEnclosingElement() || e.getModifiers().contains(FINAL) ||
+                //                                (method == null && (e.getEnclosingElement().getKind() == INSTANCE_INIT ||
+                //                                e.getEnclosingElement().getKind() == STATIC_INIT))) &&
+                //                                !illegalForwardRefs.contains(e);
                     case FIELD:
-//                        if (e.getSimpleName().contentEquals(THIS_KEYWORD) || e.getSimpleName().contentEquals(SUPER_KEYWORD))
-//                            return Utilities.startsWith(e.getSimpleName().toString(), prefix) && !isStatic;
+                        //                        if (e.getSimpleName().contentEquals(THIS_KEYWORD) || e.getSimpleName().contentEquals(SUPER_KEYWORD))
+                        //                            return Utilities.startsWith(e.getSimpleName().toString(), prefix) && !isStatic;
                         String name = e.getSimpleName().toString();
-                        return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name)
-                                &&  (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
-//                        String name = e.getSimpleName().toString();
-//                        return !name.equals(THIS_KEYWORD) && !name.equals(SUPER_KEYWORD)
-//                                && Utilities.startsWith(name, prefix);
+                        return Utilities.startsWith(name, prefix) && !CLASS_KEYWORD.equals(name) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e));
+                //                        String name = e.getSimpleName().toString();
+                //                        return !name.equals(THIS_KEYWORD) && !name.equals(SUPER_KEYWORD)
+                //                                && Utilities.startsWith(name, prefix);
                     case ENUM_CONSTANT:
-                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-//                                !illegalForwardRefs.contains(e) &&
-//                                (!isStatic || e.getModifiers().contains(STATIC)) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
+                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) && //                                !illegalForwardRefs.contains(e) &&
+                        //                                (!isStatic || e.getModifiers().contains(STATIC)) &&
+                        (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, e, (DeclaredType) t);
                     case METHOD:
-                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) &&
-                                (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) &&
-//                                (!isStatic || e.getModifiers().contains(STATIC)) &&
-                                trees.isAccessible(scope, e, (DeclaredType)t);
+                        return Utilities.startsWith(e.getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && //                                (!isStatic || e.getModifiers().contains(STATIC)) &&
+                        trees.isAccessible(scope, e, (DeclaredType) t);
                 }
                 return false;
             }
@@ -1048,51 +897,50 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         for (Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
             switch (e.getKind()) {
                 case ENUM_CONSTANT:
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, e.asType(), null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, e.asType(), smartTypes)*/, -1, null));
+                    items.add(factory.createJavaVariableItem(controller, (VariableElement) e, e.asType(), substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
                     break;
                 case FIELD:
                     String name = e.getSimpleName().toString();
                     TypeMirror tm = asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
-                    items.add(JavaCompletionItem.createVariableItem(controller, (VariableElement)e, tm, null, substitutionOffset, null, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false/*isOfSmartType(env, tm, smartTypes)*/, -1, null));
+                    items.add(factory.createJavaVariableItem(controller, (VariableElement) e, tm, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
                     break;
                 case CONSTRUCTOR:
                 case METHOD:
-                    ExecutableType et = (ExecutableType)asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
-//                    items.add(JavaCompletionItem.createExecutableItem((ExecutableElement)e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false, false/*isOfSmartType(env, et.getReturnType(), smartTypes)*/));
-                    items.add(JavadocCompletionItem.createExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
+                    ExecutableType et = (ExecutableType) asMemberOf(e, enclClass != null ? enclClass.asType() : null, types);
+                    //                    items.add(JavaCompletionItem.createExecutableItem((ExecutableElement)e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e), false, false/*isOfSmartType(env, et.getReturnType(), smartTypes)*/));
+                    items.add(factory.createJavadocExecutableItem(controller, (ExecutableElement) e, et, substitutionOffset, scope.getEnclosingClass() != e.getEnclosingElement(), elements.isDeprecated(e)));
                     break;
             }
         }
     }
 
-    private static TypeMirror asMemberOf(Element element, TypeMirror type, Types types) {
+    private TypeMirror asMemberOf(Element element, TypeMirror type, Types types) {
         TypeMirror ret = element.asType();
         TypeMirror enclType = element.getEnclosingElement().asType();
-        if (enclType.getKind() == TypeKind.DECLARED)
+        if (enclType.getKind() == TypeKind.DECLARED) {
             enclType = types.erasure(enclType);
-        while(type != null && type.getKind() == TypeKind.DECLARED) {
+        }
+        while (type != null && type.getKind() == TypeKind.DECLARED) {
             if (types.isSubtype(type, enclType)) {
-                ret = types.asMemberOf((DeclaredType)type, element);
+                ret = types.asMemberOf((DeclaredType) type, element);
                 break;
             }
-            type = ((DeclaredType)type).getEnclosingType();
+            type = ((DeclaredType) type).getEnclosingType();
         }
         return ret;
-    }       
-    
-    private void addTypes(EnumSet<ElementKind> kinds, DeclaredType baseType,
-            Set<? extends Element> toExclude, String prefix,
-            int substitutionOffset, JavadocContext jdctx) {
-        
-        if (queryType == CompletionProvider.COMPLETION_ALL_QUERY_TYPE) {
+    }
+
+    private void addTypes(EnumSet<ElementKind> kinds, DeclaredType baseType, Set<? extends Element> toExclude, String prefix, int substitutionOffset, JavadocContext jdctx) {
+        if (isAllQueryType) {
             if (baseType == null) {
                 addAllTypes(jdctx, kinds, toExclude, prefix, substitutionOffset);
             } else {
                 Elements elements = jdctx.javac.getElements();
-                for(DeclaredType subtype : getSubtypesOf(baseType, prefix, jdctx)) {
-                    TypeElement elem = (TypeElement)subtype.asElement();
-                    if ((toExclude == null || !toExclude.contains(elem)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(elem)))
-                        items.add(JavaCompletionItem.createTypeItem(jdctx.javac, elem, subtype, substitutionOffset, jdctx.getReferencesCount(), elements.isDeprecated(elem), false, false, false, false, false, null));
+                for (DeclaredType subtype : getSubtypesOf(baseType, prefix, jdctx)) {
+                    TypeElement elem = (TypeElement) subtype.asElement();
+                    if ((toExclude == null || !toExclude.contains(elem)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(elem))) {
+                        items.add(factory.createJavaTypeItem(jdctx.javac, elem, subtype, substitutionOffset, jdctx.getReferencesCount(), elements.isDeprecated(elem), false));
+                    }
                 }
             }
         } else {
@@ -1114,62 +962,58 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         final boolean isStatic = enclClass == null ? false : tu.isStaticContext(scope);
         ElementUtilities.ElementAcceptor acceptor = new ElementUtilities.ElementAcceptor() {
             public boolean accept(Element e, TypeMirror t) {
-                if ((toExclude == null || !toExclude.contains(e)) && (e.getKind().isClass() || e.getKind().isInterface() || e.getKind() == TYPE_PARAMETER)) {
+                if ((toExclude == null || !toExclude.contains(e)) && (e.getKind().isClass() || e.getKind().isInterface() || e.getKind() == ElementKind.TYPE_PARAMETER)) {
                     String name = e.getSimpleName().toString();
-                    return name.length() > 0 && !Character.isDigit(name.charAt(0)) && startsWith(name, prefix) &&
-                            (!isStatic || e.getModifiers().contains(Modifier.STATIC)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
+                    return name.length() > 0 && !Character.isDigit(name.charAt(0)) && startsWith(name, prefix) && (!isStatic || e.getModifiers().contains(Modifier.STATIC)) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
                 }
                 return false;
             }
         };
-        for(Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
+        for (Element e : controller.getElementUtilities().getLocalMembersAndVars(scope, acceptor)) {
             switch (e.getKind()) {
                 case CLASS:
                 case ENUM:
                 case INTERFACE:
                 case ANNOTATION_TYPE:
-                    items.add(JavadocCompletionItem.createTypeItem(env.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)));
+                    items.add(factory.createJavadocTypeItem(env.javac, (TypeElement) e, substitutionOffset, elements.isDeprecated(e)));
                     break;
-            }                
+            }
         }
         acceptor = new ElementUtilities.ElementAcceptor() {
             public boolean accept(Element e, TypeMirror t) {
-                if ((e.getKind().isClass() || e.getKind().isInterface())) {
-                    return (toExclude == null || !toExclude.contains(e)) && startsWith(e.getSimpleName().toString(), prefix) &&
-                            (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement)e) &&
-                            isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
+                if (e.getKind().isClass() || e.getKind().isInterface()) {
+                    return (toExclude == null || !toExclude.contains(e)) && startsWith(e.getSimpleName().toString(), prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement) e) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types);
                 }
                 return false;
             }
         };
         for (TypeElement e : controller.getElementUtilities().getGlobalTypes(acceptor)) {
-            items.add(JavadocCompletionItem.createTypeItem(env.javac, e, substitutionOffset, null, elements.isDeprecated(e)));
+            items.add(factory.createJavadocTypeItem(env.javac, e, substitutionOffset, elements.isDeprecated(e)));
         }
     }
 
     private void addAllTypes(JavadocContext env, EnumSet<ElementKind> kinds, Set<? extends Element> toExclude, String prefix, int substitutionOffset) {
-//        String prefix = env.getPrefix();
+        //        String prefix = env.getPrefix();
         CompilationInfo controller = env.javac;
         boolean isCaseSensitive = false;
-        ClassIndex.NameKind kind = 
-            isCaseSensitive? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
-//        ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
-//            Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE :
-//            Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
+        ClassIndex.NameKind kind = isCaseSensitive ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
+        //        ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
+        //            Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE :
+        //            Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
         Set<ElementHandle<Element>> excludeHandles = null;
         if (toExclude != null) {
-            excludeHandles = new HashSet<ElementHandle<Element>>(toExclude.size());
+            excludeHandles = new HashSet<>(toExclude.size());
             for (Element el : toExclude) {
                 excludeHandles.add(ElementHandle.create(el));
             }
         }
-        for(ElementHandle<TypeElement> name : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
+        for (ElementHandle<TypeElement> name : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
             if ((excludeHandles == null || !excludeHandles.contains(name)) && !isAnnonInner(name)) {
-                items.add(LazyJavaCompletionItem.createTypeItem(name, kinds, substitutionOffset, env.getReferencesCount(), controller.getSnapshot().getSource(), false, false, false, null));
+                items.add(factory.createLazyTypeItem(name, kinds, substitutionOffset, env.getReferencesCount(), controller.getSnapshot().getSource()));
             }
         }
     }
-        
+
     private void addInnerClasses(TypeElement te, EnumSet<ElementKind> kinds, DeclaredType baseType, Set<? extends Element> toExclude, String prefix, int substitutionOffset, JavadocContext jdctx) {
         CompilationInfo controller = jdctx.javac;
         Element srcEl = jdctx.handle.resolve(controller);
@@ -1182,13 +1026,13 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         for (Element e : controller.getElementUtilities().getMembers(te.asType(), null)) {
             if ((e.getKind().isClass() || e.getKind().isInterface()) && (toExclude == null || !toExclude.contains(e))) {
                 String name = e.getSimpleName().toString();
-                    if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement)e) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types)) {
-                        items.add(JavadocCompletionItem.createTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)/*, isOfSmartType(env, e.asType(), smartTypes)*/));
+                if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement) e) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types)) {
+                    items.add(factory.createJavadocTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, elements.isDeprecated(e)));
                 }
             }
         }
     }
-    
+
     private void addPackageContent(PackageElement pe, EnumSet<ElementKind> kinds, DeclaredType baseType, Set<? extends Element> toExclude, String prefix, int substitutionOffset, JavadocContext jdctx) {
         CompilationInfo controller = jdctx.javac;
         Element srcEl = jdctx.handle.resolve(controller);
@@ -1199,37 +1043,37 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         ElementUtilities eu = controller.getElementUtilities();
         TreePath docpath = srcEl != null ? trees.getPath(srcEl) : null;
         Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
-        for(Element e : pe.getEnclosedElements()) {
+        for (Element e : pe.getEnclosedElements()) {
             if ((e.getKind().isClass() || e.getKind().isInterface()) && (toExclude == null || !toExclude.contains(e))) {
                 String name = e.getSimpleName().toString();
-                    if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e))
-                        && trees.isAccessible(scope, (TypeElement)e)
-                        && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types)
-                        && !Utilities.isExcluded(eu.getElementName(e, true))) {
-                        items.add(JavadocCompletionItem.createTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, null, elements.isDeprecated(e)/*, isOfSmartType(env, e.asType(), smartTypes)*/));
+                if (Utilities.startsWith(name, prefix) && (Utilities.isShowDeprecatedMembers() || !elements.isDeprecated(e)) && trees.isAccessible(scope, (TypeElement) e) && isOfKindAndType(e.asType(), e, kinds, baseType, scope, trees, types) && !Utilities.isExcluded(eu.getElementName(e, true))) {
+                    items.add(factory.createJavadocTypeItem(jdctx.javac, (TypeElement) e, substitutionOffset, elements.isDeprecated(e)));
                 }
             }
         }
     }
-        
+
     private boolean isOfKindAndType(TypeMirror type, Element e, EnumSet<ElementKind> kinds, TypeMirror base, Scope scope, Trees trees, Types types) {
         if (type.getKind() != TypeKind.ERROR && kinds.contains(e.getKind())) {
-            if (base == null)
+            if (base == null) {
                 return true;
-            if (types.isSubtype(type, base))
+            }
+            if (types.isSubtype(type, base)) {
                 return true;
+            }
         }
-        if ((e.getKind().isClass() || e.getKind().isInterface()) && 
-            (kinds.contains(ANNOTATION_TYPE) || kinds.contains(CLASS) || kinds.contains(ENUM) || kinds.contains(INTERFACE))) {
-            DeclaredType dt = (DeclaredType)e.asType();
-            for (Element ee : e.getEnclosedElements())
-                if (trees.isAccessible(scope, ee, dt) && isOfKindAndType(ee.asType(), ee, kinds, base, scope, trees, types))
+        if ((e.getKind().isClass() || e.getKind().isInterface()) && (kinds.contains(ElementKind.ANNOTATION_TYPE) || kinds.contains(ElementKind.CLASS) || kinds.contains(ElementKind.ENUM) || kinds.contains(ElementKind.INTERFACE))) {
+            DeclaredType dt = (DeclaredType) e.asType();
+            for (Element ee : e.getEnclosedElements()) {
+                if (trees.isAccessible(scope, ee, dt) && isOfKindAndType(ee.asType(), ee, kinds, base, scope, trees, types)) {
                     return true;
+                }
+            }
         }
         return false;
     }
-    
-    private static boolean isAnnonInner(ElementHandle<TypeElement> elem) {
+
+    private boolean isAnnonInner(ElementHandle<TypeElement> elem) {
         String name = elem.getQualifiedName();
         int idx = name.lastIndexOf('.'); //NOI18N
         String simpleName = idx > -1 ? name.substring(idx + 1) : name;
@@ -1238,9 +1082,10 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
 
     /* copied from JavaCompletionProvider */
     private List<DeclaredType> getSubtypesOf(DeclaredType baseType, String prefix, JavadocContext jdctx) {
-        if (((TypeElement)baseType.asElement()).getQualifiedName().contentEquals("java.lang.Object"))
+        if (((TypeElement) baseType.asElement()).getQualifiedName().contentEquals("java.lang.Object")) {
             return Collections.emptyList();
-        LinkedList<DeclaredType> subtypes = new LinkedList<DeclaredType>();
+        }
+        LinkedList<DeclaredType> subtypes = new LinkedList<>();
         CompilationInfo controller = jdctx.javac;
         Types types = controller.getTypes();
         Trees trees = controller.getTrees();
@@ -1250,31 +1095,32 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
         Scope scope = docpath != null ? trees.getScope(docpath) : tu.scopeFor(caretOffset);
         if (prefix != null && prefix.length() > 2 && baseType.getTypeArguments().isEmpty()) {
             // XXX resolve camels
-//            ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
-            ClassIndex.NameKind kind = false ?
-                Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE :
-                Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
-            for(ElementHandle<TypeElement> handle : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
+            //            ClassIndex.NameKind kind = env.isCamelCasePrefix() ?
+            ClassIndex.NameKind kind = false ? Utilities.isCaseSensitive() ? ClassIndex.NameKind.CAMEL_CASE : ClassIndex.NameKind.CAMEL_CASE_INSENSITIVE : Utilities.isCaseSensitive() ? ClassIndex.NameKind.PREFIX : ClassIndex.NameKind.CASE_INSENSITIVE_PREFIX;
+            for (ElementHandle<TypeElement> handle : controller.getClasspathInfo().getClassIndex().getDeclaredTypes(prefix, kind, EnumSet.allOf(ClassIndex.SearchScope.class))) {
                 TypeElement te = handle.resolve(controller);
-                if (te != null && trees.isAccessible(scope, te) && types.isSubtype(types.getDeclaredType(te), baseType))
+                if (te != null && trees.isAccessible(scope, te) && types.isSubtype(types.getDeclaredType(te), baseType)) {
                     subtypes.add(types.getDeclaredType(te));
+                }
             }
         } else {
-            HashSet<TypeElement> elems = new HashSet<TypeElement>();
-            LinkedList<DeclaredType> bases = new LinkedList<DeclaredType>();
+            HashSet<TypeElement> elems = new HashSet<>();
+            LinkedList<DeclaredType> bases = new LinkedList<>();
             bases.add(baseType);
             ClassIndex index = controller.getClasspathInfo().getClassIndex();
-            while(!bases.isEmpty()) {
+            while (!bases.isEmpty()) {
                 DeclaredType head = bases.remove();
-                TypeElement elem = (TypeElement)head.asElement();
-                if (!elems.add(elem))
+                TypeElement elem = (TypeElement) head.asElement();
+                if (!elems.add(elem)) {
                     continue;
-                if (startsWith(elem.getSimpleName().toString(), prefix) && trees.isAccessible(scope, elem))
+                }
+                if (startsWith(elem.getSimpleName().toString(), prefix) && trees.isAccessible(scope, elem)) {
                     subtypes.add(head);
+                }
                 List<? extends TypeMirror> tas = head.getTypeArguments();
                 boolean isRaw = !tas.iterator().hasNext();
                 subtypes:
-                for (ElementHandle<TypeElement> eh : index.getElements(ElementHandle.create(elem), EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS),EnumSet.allOf(ClassIndex.SearchScope.class))) {
+                for (ElementHandle<TypeElement> eh : index.getElements(ElementHandle.create(elem), EnumSet.of(ClassIndex.SearchKind.IMPLEMENTORS), EnumSet.allOf(ClassIndex.SearchScope.class))) {
                     TypeElement e = eh.resolve(controller);
                     if (e != null) {
                         if (trees.isAccessible(scope, e)) {
@@ -1282,18 +1128,18 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                                 DeclaredType dt = types.getDeclaredType(e);
                                 bases.add(dt);
                             } else {
-                                HashMap<Element, TypeMirror> map = new HashMap<Element, TypeMirror>();
+                                HashMap<Element, TypeMirror> map = new HashMap<>();
                                 TypeMirror sup = e.getSuperclass();
-                                if (sup.getKind() == TypeKind.DECLARED && ((DeclaredType)sup).asElement() == elem) {
-                                    DeclaredType dt = (DeclaredType)sup;
+                                if (sup.getKind() == TypeKind.DECLARED && ((DeclaredType) sup).asElement() == elem) {
+                                    DeclaredType dt = (DeclaredType) sup;
                                     Iterator<? extends TypeMirror> ittas = tas.iterator();
                                     Iterator<? extends TypeMirror> it = dt.getTypeArguments().iterator();
-                                    while(it.hasNext() && ittas.hasNext()) {
+                                    while (it.hasNext() && ittas.hasNext()) {
                                         TypeMirror basetm = ittas.next();
                                         TypeMirror stm = it.next();
                                         if (basetm != stm) {
                                             if (stm.getKind() == TypeKind.TYPEVAR) {
-                                                map.put(((TypeVariable)stm).asElement(), basetm);
+                                                map.put(((TypeVariable) stm).asElement(), basetm);
                                             } else {
                                                 continue subtypes;
                                             }
@@ -1304,16 +1150,16 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                                     }
                                 } else {
                                     for (TypeMirror tm : e.getInterfaces()) {
-                                        if (((DeclaredType)tm).asElement() == elem) {
-                                            DeclaredType dt = (DeclaredType)tm;
+                                        if (((DeclaredType) tm).asElement() == elem) {
+                                            DeclaredType dt = (DeclaredType) tm;
                                             Iterator<? extends TypeMirror> ittas = tas.iterator();
                                             Iterator<? extends TypeMirror> it = dt.getTypeArguments().iterator();
-                                            while(it.hasNext() && ittas.hasNext()) {
+                                            while (it.hasNext() && ittas.hasNext()) {
                                                 TypeMirror basetm = ittas.next();
                                                 TypeMirror stm = it.next();
                                                 if (basetm != stm) {
                                                     if (stm.getKind() == TypeKind.TYPEVAR) {
-                                                        map.put(((TypeVariable)stm).asElement(), basetm);
+                                                        map.put(((TypeVariable) stm).asElement(), basetm);
                                                     } else {
                                                         continue subtypes;
                                                     }
@@ -1330,10 +1176,7 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
                             }
                         }
                     } else {
-                        Logger.getLogger("global").log(Level.FINE, String.format("Cannot resolve: %s on bootpath: %s classpath: %s sourcepath: %s\n", eh.toString(),
-                                controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.BOOT),
-                                controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.COMPILE),
-                                controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.SOURCE)));
+                        Logger.getLogger("global").log(Level.FINE, String.format("Cannot resolve: %s on bootpath: %s classpath: %s sourcepath: %s\n", eh.toString(), controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.BOOT), controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.COMPILE), controller.getClasspathInfo().getClassPath(ClasspathInfo.PathKind.SOURCE)));
                     }
                 }
             }
@@ -1351,24 +1194,21 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
             targs[i++] = t != null ? t : tpe.asType();
         }
         Element encl = e.getEnclosingElement();
-        if ((encl.getKind().isClass() || encl.getKind().isInterface()) && !((TypeElement)encl).getTypeParameters().isEmpty())
-                return types.getDeclaredType(getDeclaredType((TypeElement)encl, map, types), e, targs);
+        if ((encl.getKind().isClass() || encl.getKind().isInterface()) && !((TypeElement) encl).getTypeParameters().isEmpty()) {
+            return types.getDeclaredType(getDeclaredType((TypeElement) encl, map, types), e, targs);
+        }
         return types.getDeclaredType(e, targs);
     }
 
     private boolean startsWith(String theString, String prefix) {
         // XXX isCamelCasePrefix
-        return /*env.isCamelCasePrefix()*/false ? Utilities.isCaseSensitive() ? 
-            Utilities.startsWithCamelCase(theString, prefix) : 
-            Utilities.startsWithCamelCase(theString, prefix) || Utilities.startsWith(theString, prefix) :
-            Utilities.startsWith(theString, prefix);
+        return /*env.isCamelCasePrefix()*/ false ? Utilities.isCaseSensitive() ? Utilities.startsWithCamelCase(theString, prefix) : Utilities.startsWithCamelCase(theString, prefix) || Utilities.startsWith(theString, prefix) : Utilities.startsWith(theString, prefix);
     }
-    
+
     void resolveOtherText(JavadocContext jdctx, TokenSequence<JavadocTokenId> jdts) {
         Token<JavadocTokenId> token = jdts.token();
         assert token != null;
         assert token.id() == JavadocTokenId.OTHER_TEXT;
-
         CharSequence text = token.text();
         int pos = caretOffset - jdts.offset();
         DocTreePath tag = getTag(jdctx, caretOffset);
@@ -1382,7 +1222,6 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
             resolveInlineTag(null, jdctx);
             return;
         }
-        
         if (tag != null) {
             insideTag(tag, jdctx);
             if (JavadocCompletionUtils.isBlockTag(tag) && JavadocCompletionUtils.isLineBreak(token, pos)) {
@@ -1392,22 +1231,27 @@ final class JavadocCompletionQuery extends AsyncCompletionQuery{
             resolveBlockTag(null, jdctx);
         }
     }
-    
-    static final class JavadocContext {
-        int anchorOffset = -1;
-        ElementHandle<Element> handle;
-        Element commentFor;
-        DocCommentTree comment;
-        DocSourcePositions positions;
-        TokenSequence<JavadocTokenId> jdts;
-        Document doc;
-        CompilationInfo javac;
+
+    private static class JavadocContext {
+
+        private final CompilationInfo javac;
+        private ElementHandle<Element> handle;
+        private Element commentFor;
+        private DocCommentTree comment;
+        private DocSourcePositions positions;
+        private TokenSequence<JavadocTokenId> jdts;
+        private Document doc;
         private ReferencesCount count;
         private TreePath javadocFor;
-        ReferencesCount getReferencesCount() {
+
+        private JavadocContext(CompilationInfo javac) {
+            this.javac = javac;
+        }
+
+        private ReferencesCount getReferencesCount() {
             if (count == null)
                 count = ReferencesCount.get(javac.getClasspathInfo());
             return count;
         }
-    }    
+    }
 }
diff --git a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/TagRegistery.java b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/TagRegistery.java
index 5b4f67fd0c..c8384251be 100644
--- a/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/TagRegistery.java
+++ b/java/java.editor/src/org/netbeans/modules/java/editor/javadoc/TagRegistery.java
@@ -101,7 +101,15 @@ final class TagRegistery {
         
         addTag("@code", true, ALL_KINDS);
         addTag("@snippet", true, ALL_KINDS);
+        addTag("@summary", true, ALL_KINDS);
+        addTag("@systemProperty", true, EnumSet.<ElementKind>of(
+            ElementKind.ANNOTATION_TYPE, ElementKind.CLASS,
+            ElementKind.CONSTRUCTOR, ElementKind.ENUM,
+            ElementKind.ENUM_CONSTANT, ElementKind.FIELD,
+            ElementKind.INTERFACE, ElementKind.METHOD,
+            ElementKind.MODULE, ElementKind.PACKAGE));
         addTag("@docRoot", true, ALL_KINDS);
+        addTag("@index", true, ALL_KINDS);
         // just in empty tag description
         addTag("@inheritDoc", true, EnumSet.of(ElementKind.METHOD));
         addTag("@link", true, ALL_KINDS);
diff --git a/java/java.editor/test/unit/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQueryTest.java b/java/java.editor/test/unit/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQueryTest.java
index ac02447e55..74e42e0f69 100644
--- a/java/java.editor/test/unit/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQueryTest.java
+++ b/java/java.editor/test/unit/src/org/netbeans/modules/java/editor/javadoc/JavadocCompletionQueryTest.java
@@ -45,6 +45,238 @@ public class JavadocCompletionQueryTest extends JavadocTestSupport {
         return suite;
     }
     
+    public void testBlockTagsCompletion() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * |\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@deprecated:", "@exception:", "@hidden:", "@param:", "@return:", "@see:", "@serialData:", "@since:", "@throws:");
+    }
+    
+    public void testBlockTagsCompletion1() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * This is javadoc for method.\n" +
+                "     * |\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@deprecated:", "@exception:", "@hidden:", "@param:", "@return:", "@see:", "@serialData:", "@since:", "@throws:");
+    }
+    
+    public void testBlockTagsCompletion2() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * @|\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@deprecated:", "@exception:", "@hidden:", "@param:", "@return:", "@see:", "@serialData:", "@since:", "@throws:");
+    }
+    
+    public void testBlockTagsCompletion3() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * This is javadoc for method.\n" +
+                "     * @|\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@deprecated:", "@exception:", "@hidden:", "@param:", "@return:", "@see:", "@serialData:", "@since:", "@throws:");
+    }
+    
+    public void testBlockTagsCompletion4() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * @p|\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@param:");
+    }
+    
+    public void testBlockTagsCompletion5() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * This is javadoc for method.\n" +
+                "     * @p|\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@param:");
+    }
+    
+    public void testBlockTagsCompletion6() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * @p|aram\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@param:");
+    }
+    
+    public void testBlockTagsCompletion7() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * This is javadoc for method.\n" +
+                "     * @p|aram\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@param:");
+    }
+    
+    public void testInlineTagsCompletion() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * {|\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@code:", "@docRoot:", "@index:", "@inheritDoc:", "@link:", "@linkplain:", "@literal:", "@snippet:", "@summary:", "@systemProperty:");
+    }
+    
+    public void testInlineTagsCompletion1() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * This is javadoc for method.\n" +
+                "     * {|\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@code:", "@docRoot:", "@index:", "@inheritDoc:", "@link:", "@linkplain:", "@literal:", "@snippet:", "@summary:", "@systemProperty:");
+    }
+
+    public void testInlineTagsCompletion2() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * {@|\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@code:", "@docRoot:", "@index:", "@inheritDoc:", "@link:", "@linkplain:", "@literal:", "@snippet:", "@summary:", "@systemProperty:");
+    }
+    
+    public void testInlineTagsCompletion3() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * This is javadoc for method.\n" +
+                "     * {@|\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@code:", "@docRoot:", "@index:", "@inheritDoc:", "@link:", "@linkplain:", "@literal:", "@snippet:", "@summary:", "@systemProperty:");
+    }
+
+    public void testInlineTagsCompletion4() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * {@l|\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@link:", "@linkplain:", "@literal:");
+    }
+    
+    public void testInlineTagsCompletion5() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * This is javadoc for method.\n" +
+                "     * {@l|\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@link:", "@linkplain:", "@literal:");
+    }
+
+    public void testInlineTagsCompletion6() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * {@l|ink\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@link:", "@linkplain:", "@literal:");
+    }
+    
+    public void testInlineTagsCompletion7() throws Exception {
+        String code =
+                "package p;\n" +
+                "class Clazz {\n" +
+                "    /**\n" +
+                "     * This is javadoc for method.\n" +
+                "     * {@l|ink\n" +
+                "     */\n" +
+                "    void method(int p1, int p2) {\n" +
+                "    }\n" +
+                "}\n";
+        
+        performCompletionTest(code, "@link:", "@linkplain:", "@literal:");
+    }
+
     public void testParamNameCompletionForMethod() throws Exception {
         String code =
                 "package p;\n" +
@@ -117,17 +349,16 @@ public class JavadocCompletionQueryTest extends JavadocTestSupport {
         performCompletionTest(code, "p1:", "p2:");
     }
     
-    public void XtestParamNameCompletionForClass() throws Exception {
-        //XXX: ???
+    public void testParamNameCompletionForClass() throws Exception {
         String code =
                 "package p;\n" +
                 "/**\n" +
-                " * @param P|\n" +
+                " * @param <P|\n" +
                 " */\n" +
                 "class Clazz<P1,P2> {\n" +
                 "}\n";
         
-        performCompletionTest(code, "P1:", "P2:");
+        performCompletionTest(code, "&lt;P1&gt;:", "&lt;P2&gt;:");
     }
     
     public void testLink1() throws Exception {
diff --git a/java/java.lsp.server/nbcode/nbproject/platform.properties b/java/java.lsp.server/nbcode/nbproject/platform.properties
index d48788bbc4..db5d41b90b 100644
--- a/java/java.lsp.server/nbcode/nbproject/platform.properties
+++ b/java/java.lsp.server/nbcode/nbproject/platform.properties
@@ -153,7 +153,6 @@ disabled.modules=\
     org.netbeans.modules.html.custom,\
     org.netbeans.modules.html.editor,\
     org.netbeans.modules.html.knockout,\
-    org.netbeans.modules.html.parser,\
     org.netbeans.modules.html.validation,\
     org.netbeans.modules.httpserver,\
     org.netbeans.modules.hudson,\
@@ -190,7 +189,6 @@ disabled.modules=\
     org.netbeans.modules.java.navigation,\
     org.netbeans.modules.java.source.compat8,\
     org.netbeans.modules.java.testrunner.ant,\
-    org.netbeans.modules.javadoc,\
     org.netbeans.modules.javascript.bower,\
     org.netbeans.modules.javascript.cdnjs,\
     org.netbeans.modules.javascript.grunt,\
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
index 0da258c35c..b1e26e645b 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
@@ -702,7 +702,7 @@ public final class Server {
                 capabilities.setTextDocumentSync(textDocumentSyncOptions);
                 CompletionOptions completionOptions = new CompletionOptions();
                 completionOptions.setResolveProvider(true);
-                completionOptions.setTriggerCharacters(Collections.singletonList("."));
+                completionOptions.setTriggerCharacters(Arrays.asList(".", "#", "@", "*"));
                 capabilities.setCompletionProvider(completionOptions);
                 capabilities.setHoverProvider(true);
                 CodeActionOptions codeActionOptions = new CodeActionOptions(Arrays.asList(CodeActionKind.QuickFix, CodeActionKind.Source, CodeActionKind.SourceOrganizeImports, CodeActionKind.Refactor));
diff --git a/java/javadoc/nbproject/project.xml b/java/javadoc/nbproject/project.xml
index 94f56cdfb0..595112181d 100644
--- a/java/javadoc/nbproject/project.xml
+++ b/java/javadoc/nbproject/project.xml
@@ -43,6 +43,15 @@
                         <specification-version>1.0</specification-version>
                     </run-dependency>
                 </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.api.lsp</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.10</specification-version>
+                    </run-dependency>
+                </dependency>
                 <dependency>
                     <code-name-base>org.netbeans.libs.javacapi</code-name-base>
                     <build-prerequisite/>
diff --git a/java/javadoc/src/org/netbeans/modules/javadoc/hints/GenerateJavadocCollector.java b/java/javadoc/src/org/netbeans/modules/javadoc/hints/GenerateJavadocCollector.java
new file mode 100644
index 0000000000..88dee530e4
--- /dev/null
+++ b/java/javadoc/src/org/netbeans/modules/javadoc/hints/GenerateJavadocCollector.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.javadoc.hints;
+
+import com.sun.source.tree.Tree;
+import com.sun.source.util.TreePath;
+import java.io.IOException;
+import java.util.function.Consumer;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.swing.text.Document;
+import org.netbeans.api.editor.mimelookup.MimeRegistration;
+import org.netbeans.api.java.lexer.JavaTokenId;
+import org.netbeans.api.java.source.CompilationController;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.SourceUtils;
+import org.netbeans.api.java.source.Task;
+import org.netbeans.api.java.source.TreeUtilities;
+import org.netbeans.api.lexer.TokenHierarchy;
+import org.netbeans.api.lexer.TokenSequence;
+import org.netbeans.api.lsp.Completion;
+import org.netbeans.spi.lsp.CompletionCollector;
+import org.openide.filesystems.FileObject;
+import org.openide.util.Exceptions;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Dusan Balek
+ */
+@MimeRegistration(mimeType = "text/x-java", service = CompletionCollector.class) //NOI18N
+public class GenerateJavadocCollector implements CompletionCollector {
+
+    @NbBundle.Messages({
+        "DN_JavadocComment=Javadoc comment",
+    })
+    @Override
+    public boolean collectCompletions(Document doc, int offset, Completion.Context context, Consumer<Completion> consumer) {
+        if (context != null && context.getTriggerKind() == Completion.TriggerKind.TriggerCharacter && context.getTriggerCharacter() == '*') {
+            TokenSequence<JavaTokenId> ts = SourceUtils.getJavaTokenSequence(TokenHierarchy.get(doc), offset);
+            if (ts != null) {
+                ts.move(offset);
+                if (ts.moveNext() && ts.token().id() == JavaTokenId.JAVADOC_COMMENT) {
+                    int jdBeginOffset = ts.offset();
+                    String text = ts.token().text().toString();
+                    if (text.substring(3, text.length() - 2).trim().isEmpty()) {
+                        JavaSource js = JavaSource.forDocument(doc);
+                        if (js != null) {
+                            FileObject file = js.getFileObjects().iterator().next();
+                            SourceVersion sv = JavadocUtilities.resolveSourceVersion(file);
+                            final JavadocGenerator gen = new JavadocGenerator(sv);
+                            gen.updateSettings(file);
+                            try {
+                                js.runUserActionTask(new Task<CompilationController>() {
+                                    @Override
+                                    public void run(CompilationController cc) throws Exception {
+                                        cc.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
+                                        int offsetBehindJavadoc = ts.offset() + ts.token().length();
+                                        while (ts.moveNext()) {
+                                            JavaTokenId tid = ts.token().id();
+                                            if (tid != JavaTokenId.WHITESPACE && tid != JavaTokenId.LINE_COMMENT && tid != JavaTokenId.BLOCK_COMMENT) {
+                                                offsetBehindJavadoc = ts.offset() + 1;
+                                                break;
+                                            }
+                                        }
+                                        TreePath tp = cc.getTreeUtilities().pathFor(offsetBehindJavadoc);
+                                        while (tp != null && !TreeUtilities.CLASS_TREE_KINDS.contains(tp.getLeaf().getKind())
+                                                && tp.getLeaf().getKind() != Tree.Kind.METHOD && tp.getLeaf().getKind() != Tree.Kind.VARIABLE) {
+                                            tp = tp.getParentPath();
+                                        }
+                                        if (tp != null && cc.getTrees().getSourcePositions().getStartPosition(tp.getCompilationUnit(), tp.getLeaf()) >= jdBeginOffset) {
+                                            Element el = cc.getTrees().getElement(tp);
+                                            if (el != null) {
+                                                String javadoc = gen.generateComment(el, cc);
+                                                if (javadoc != null) {
+                                                    StringBuilder sb = new StringBuilder("\n * ${0}"); //NOI18N
+                                                    boolean first = true;
+                                                    for (String s : javadoc.split("\n")) { //NOI18N
+                                                        if (first && s.isEmpty()) {
+                                                            sb.append('\n');
+                                                        } else {
+                                                            sb.append(" * ").append(s).append('\n'); //NOI18N
+                                                        }
+                                                        first = false;
+                                                    }
+                                                    consumer.accept(CompletionCollector.newBuilder(Bundle.DN_JavadocComment())
+                                                            .kind(Completion.Kind.Snippet)
+                                                            .insertText(sb.toString())
+                                                            .insertTextFormat(Completion.TextFormat.Snippet)
+                                                            .documentation(javadoc)
+                                                            .build());
+                                                }
+                                            }
+                                        }
+                                    }
+                                }, true);
+                            } catch (IOException ex) {
+                                Exceptions.printStackTrace(ex);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return true;
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists