/*
 * 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.completion;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.Callable;

import javax.lang.model.element.Element;
import static javax.lang.model.element.ElementKind.METHOD;
import javax.lang.model.element.ExecutableElement;
import static javax.lang.model.element.Modifier.*;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;

import com.sun.source.tree.*;
import com.sun.source.tree.Tree.Kind;
import com.sun.source.util.SourcePositions;
import com.sun.source.util.TreePath;
import org.netbeans.api.java.source.support.ErrorAwareTreeScanner;
import javax.lang.model.element.Name;

import org.netbeans.api.java.lexer.JavaTokenId;
import org.netbeans.api.java.source.*;
import org.netbeans.api.java.source.support.ReferencesCount;
import org.netbeans.api.lexer.TokenSequence;
import org.netbeans.modules.parsing.api.ResultIterator;
import org.netbeans.modules.parsing.api.UserTask;
import org.netbeans.modules.parsing.spi.Parser;

/**
 *
 * @author Dusan Balek
 */
abstract class BaseTask extends UserTask {

    protected final int caretOffset;
    protected final Callable<Boolean> cancel;
    private int caretInSnapshot;

    protected BaseTask(int caretOffset, Callable<Boolean> cancel) {
        this.caretOffset = caretOffset;
        this.cancel = cancel;
    }

    
    final int getCaretInSnapshot() {
        return caretInSnapshot;
    }
    
    private CompilationController controller;
    
    final int snapshotPos(int pos) {
        if (pos < 0) {
            return pos;
        }
        int r = controller.getSnapshot().getEmbeddedOffset(pos);
        if (r == -1) {
            return pos;
        } else {
            return r;
        }
    }

    @Override
    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())) {
            try {
                this.controller = controller;
                caretInSnapshot = snapshotPos(caretOffset);
                resolve(controller);
            } finally {
                this.controller = null;
            }
        }
    }

    protected abstract void resolve(CompilationController controller) throws IOException;

    Tree unwrapErrTree(Tree tree) {
        if (tree != null && tree.getKind() == Tree.Kind.ERRONEOUS) {
            Iterator<? extends Tree> it = ((ErroneousTree) tree).getErrorTrees().iterator();
            tree = it.hasNext() ? it.next() : null;
        }
        return tree;
    }

    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 ((enclType.getKind() != TypeKind.DECLARED || ((DeclaredType) enclType).asElement().getSimpleName().length() > 0) && types.isSubtype(type, enclType)) {
                ret = types.asMemberOf((DeclaredType) type, element);
                break;
            }
            type = ((DeclaredType) type).getEnclosingType();
        }
        return ret;
    }

    List<Tree> getArgumentsUpToPos(Env env, Iterable<? extends ExpressionTree> args, int startPos, int position, boolean strict) {
        List<Tree> ret = new ArrayList<>();
        CompilationUnitTree root = env.getRoot();
        SourcePositions sourcePositions = env.getSourcePositions();
        if (args == null) {
            return null; //TODO: member reference???
        }
        for (ExpressionTree e : args) {
            int pos = (int) sourcePositions.getEndPosition(root, e);
            if (pos != Diagnostic.NOPOS && (position > pos || !strict && position == pos)) {
                startPos = pos;
                ret.add(e);
            } else {
                break;
            }
        }
        if (startPos < 0) {
            return ret;
        }
        if (position >= startPos) {
            TokenSequence<JavaTokenId> last = findLastNonWhitespaceToken(env, startPos, position);
            if (last == null) {
                if (!strict && !ret.isEmpty()) {
                    ret.remove(ret.size() - 1);
                    return ret;
                }
            } else if (last.token().id() == JavaTokenId.LPAREN || last.token().id() == JavaTokenId.COMMA) {
                return ret;
            }
        }
        return null;
    }

    TokenSequence<JavaTokenId> findFirstNonWhitespaceToken(Env env, int startPos, int endPos) {
        TokenSequence<JavaTokenId> ts = env.getController().getTokenHierarchy().tokenSequence(JavaTokenId.language());
        ts.move(startPos);
        ts = nextNonWhitespaceToken(ts);
        if (ts == null || ts.offset() >= endPos) {
            return null;
        }
        return ts;
    }

    TokenSequence<JavaTokenId> nextNonWhitespaceToken(TokenSequence<JavaTokenId> ts) {
        while (ts.moveNext()) {
            switch (ts.token().id()) {
                case WHITESPACE:
                case LINE_COMMENT:
                case BLOCK_COMMENT:
                case JAVADOC_COMMENT:
                    break;
                default:
                    return ts;
            }
        }
        return null;
    }

    TokenSequence<JavaTokenId> findLastNonWhitespaceToken(Env env, Tree tree, int position) {
        int startPos = (int) env.getSourcePositions().getStartPosition(env.getRoot(), tree);
        return findLastNonWhitespaceToken(env, startPos, position);
    }

    TokenSequence<JavaTokenId> findLastNonWhitespaceToken(Env env, int startPos, int endPos) {
        TokenSequence<JavaTokenId> ts = env.getController().getTokenHierarchy().tokenSequence(JavaTokenId.language());
        ts.move(endPos);
        ts = previousNonWhitespaceToken(ts);
        if (ts == null || ts.offset() < startPos) {
            return null;
        }
        return ts;
    }

    TokenSequence<JavaTokenId> previousNonWhitespaceToken(TokenSequence<JavaTokenId> ts) {
        while (ts.movePrevious()) {
            switch (ts.token().id()) {
                case WHITESPACE:
                case LINE_COMMENT:
                case BLOCK_COMMENT:
                case JAVADOC_COMMENT:
                    break;
                default:
                    return ts;
            }
        }
        return null;
    }

    Env getCompletionEnvironment(CompilationController controller, boolean bottomUpSearch) throws IOException {
        controller.toPhase(JavaSource.Phase.PARSED);
        int offset = controller.getSnapshot().getEmbeddedOffset(caretOffset);
        if (offset < 0 || offset > controller.getText().length()) {
            return null;
        }
        String prefix = null;
        if (offset > 0) {
            if (bottomUpSearch) {
                TokenSequence<JavaTokenId> ts = controller.getTokenHierarchy().tokenSequence(JavaTokenId.language());
                // When right at the token end move to previous token; otherwise move to the token that "contains" the offset
                if (ts.move(offset) == 0 || !ts.moveNext()) {
                    ts.movePrevious();
                }
                int len = offset - ts.offset();
                if (len > 0 && ts.token().length() >= len) {
                    if (ts.token().id() == JavaTokenId.IDENTIFIER
                            || ts.token().id().primaryCategory().startsWith("keyword") || //NOI18N
                            ts.token().id().primaryCategory().startsWith("string") || //NOI18N
                            ts.token().id().primaryCategory().equals("literal")) //NOI18N
                    { //TODO: Use isKeyword(...) when available
                        prefix = ts.token().text().toString().substring(0, len);
                        offset = ts.offset();
                    } else if ((ts.token().id() == JavaTokenId.DOUBLE_LITERAL
                            || ts.token().id() == JavaTokenId.FLOAT_LITERAL
                            || ts.token().id() == JavaTokenId.FLOAT_LITERAL_INVALID
                            || ts.token().id() == JavaTokenId.LONG_LITERAL)
                            && ts.token().text().charAt(0) == '.') {
                        prefix = ts.token().text().toString().substring(1, len);
                        offset = ts.offset() + 1;
                    }
                }
            } else {
                TokenSequence<JavaTokenId> ts = controller.getTokenHierarchy().tokenSequence(JavaTokenId.language());
                // When right at the token start move offset to the position "inside" the token
                ts.move(offset);
                if (!ts.moveNext()) {
                    ts.movePrevious();
                }
                if (ts.offset() == offset && ts.token().length() > 0
                        && (ts.token().id() == JavaTokenId.IDENTIFIER
                        || ts.token().id().primaryCategory().startsWith("keyword") || //NOI18N
                        ts.token().id().primaryCategory().startsWith("string") || //NOI18N
                        ts.token().id().primaryCategory().equals("literal"))) { //NOI18N
                    offset++;
                }
            }
        }
        offset = Math.min(offset, controller.getText().length());
        TreePath path = controller.getTreeUtilities().pathFor(offset);
        if (bottomUpSearch) {
            TreePath treePath = path;
            while (treePath != null) {
                TreePath pPath = treePath.getParentPath();
                TreePath gpPath = pPath != null ? pPath.getParentPath() : null;
                JavaCompletionTask.Env env = getEnvImpl(controller, path, treePath, pPath, gpPath, offset, prefix, true);
                if (env != null) {
                    return env;
                }
                treePath = treePath.getParentPath();
            }
        } else {
            if (JavaSource.Phase.RESOLVED.compareTo(controller.getPhase()) > 0) {
                LinkedList<TreePath> reversePath = new LinkedList<>();
                TreePath treePath = path;
                while (treePath != null) {
                    reversePath.addFirst(treePath);
                    treePath = treePath.getParentPath();
                }
                for (TreePath tp : reversePath) {
                    TreePath pPath = tp.getParentPath();
                    TreePath gpPath = pPath != null ? pPath.getParentPath() : null;
                    Env env = getEnvImpl(controller, path, tp, pPath, gpPath, offset, prefix, false);
                    if (env != null) {
                        return env;
                    }
                }
            }
        }
        return new Env(offset, prefix, controller, path, controller.getTrees().getSourcePositions(), null);
    }

    private Env getEnvImpl(CompilationController controller, TreePath orig, TreePath path, TreePath pPath, TreePath gpPath, int offset, String prefix, boolean upToOffset) throws IOException {
        Tree tree = path != null ? path.getLeaf() : null;
        Tree parent = pPath != null ? pPath.getLeaf() : null;
        Tree grandParent = gpPath != null ? gpPath.getLeaf() : null;
        SourcePositions sourcePositions = controller.getTrees().getSourcePositions();
        CompilationUnitTree root = controller.getCompilationUnit();
        TreeUtilities tu = controller.getTreeUtilities();
        if (upToOffset && TreeUtilities.CLASS_TREE_KINDS.contains(tree.getKind())) {
            controller.toPhase(withinAnonymousOrLocalClass(tu, path) ? JavaSource.Phase.RESOLVED : JavaSource.Phase.ELEMENTS_RESOLVED);
            return new Env(offset, prefix, controller, orig, sourcePositions, null);
        } else if (parent != null && tree.getKind() == Tree.Kind.BLOCK
                && (parent.getKind() == Tree.Kind.METHOD || TreeUtilities.CLASS_TREE_KINDS.contains(parent.getKind()))) {
            controller.toPhase(withinAnonymousOrLocalClass(tu, path) ? JavaSource.Phase.RESOLVED : JavaSource.Phase.ELEMENTS_RESOLVED);
            int blockPos = (int) sourcePositions.getStartPosition(root, tree);
            String blockText = controller.getText().substring(blockPos, upToOffset ? offset : (int) sourcePositions.getEndPosition(root, tree));
            final SourcePositions[] sp = new SourcePositions[1];
            final StatementTree block = (((BlockTree) tree).isStatic() ? tu.parseStaticBlock(blockText, sp) : tu.parseStatement(blockText, sp));
            if (block == null) {
                return null;
            }
            sourcePositions = new SourcePositionsImpl(block, sourcePositions, sp[0], blockPos, upToOffset ? offset : -1);
            Scope scope = controller.getTrees().getScope(path);
            path = tu.pathFor(new TreePath(pPath, block), offset, sourcePositions);
            if (upToOffset) {
                Tree last = path.getLeaf();
                List<? extends StatementTree> stmts = null;
                switch (path.getLeaf().getKind()) {
                    case BLOCK:
                        stmts = ((BlockTree) path.getLeaf()).getStatements();
                        break;
                    case FOR_LOOP:
                        stmts = ((ForLoopTree) path.getLeaf()).getInitializer();
                        break;
                    case ENHANCED_FOR_LOOP:
                        stmts = Collections.singletonList(((EnhancedForLoopTree) path.getLeaf()).getStatement());
                        break;
                    case METHOD:
                        stmts = ((MethodTree) path.getLeaf()).getParameters();
                        break;
                    case SWITCH:
                        CaseTree lastCase = null;
                        for (CaseTree caseTree : ((SwitchTree) path.getLeaf()).getCases()) {
                            lastCase = caseTree;
                        }
                        if (lastCase != null) {
                            stmts = lastCase.getStatements();
                        }
                        break;
                    case CASE:
                        stmts = ((CaseTree) path.getLeaf()).getStatements();
                        break;
                    case CONDITIONAL_AND: case CONDITIONAL_OR:
                        BinaryTree bt = (BinaryTree) last;
                        if (sourcePositions.getStartPosition(path.getCompilationUnit(), bt.getRightOperand()) == offset &&
                            bt.getRightOperand().getKind() == Kind.ERRONEOUS) {
                            last = bt.getRightOperand();
                        }
                        break;
                }
                if (stmts != null) {
                    for (StatementTree st : stmts) {
                        if (sourcePositions.getEndPosition(root, st) <= offset) {
                            last = st;
                        }
                    }
                }
                scope = tu.reattributeTreeTo(block, scope, last);
            } else {
                tu.reattributeTreeTo(block, scope, block);
            }
            return new Env(offset, prefix, controller, path, sourcePositions, scope);
        } else if (tree.getKind() == Tree.Kind.LAMBDA_EXPRESSION) {
            controller.toPhase(JavaSource.Phase.RESOLVED);
            Tree lambdaBody = ((LambdaExpressionTree) tree).getBody();
            Scope scope = null;
            TreePath blockPath = path.getParentPath();
            int bodyPos = 0;
            while (blockPath != null) {
                if (blockPath.getLeaf().getKind() == Tree.Kind.BLOCK) {
                    if (blockPath.getParentPath().getLeaf().getKind() == Tree.Kind.METHOD
                            || TreeUtilities.CLASS_TREE_KINDS.contains(blockPath.getParentPath().getLeaf().getKind())) {
                        final int blockPos = (int) sourcePositions.getStartPosition(root, blockPath.getLeaf());
                        final String blockText = upToOffset && getCaretInSnapshot() > offset
                                ? controller.getText().substring(blockPos, offset) + whitespaceString(getCaretInSnapshot() - offset) + controller.getText().substring(getCaretInSnapshot(), (int) sourcePositions.getEndPosition(root, blockPath.getLeaf()))
                                : controller.getText().substring(blockPos, (int) sourcePositions.getEndPosition(root, blockPath.getLeaf()));
                        final SourcePositions[] sp = new SourcePositions[1];
                        final StatementTree block = (((BlockTree) blockPath.getLeaf()).isStatic() ? tu.parseStaticBlock(blockText, sp) : tu.parseStatement(blockText, sp));
                        if (block == null) {
                            return null;
                        }
                        sourcePositions = new SourcePositionsImpl(block, sourcePositions, sp[0], blockPos, -1);
                        path = tu.getPathElementOfKind(Tree.Kind.LAMBDA_EXPRESSION, tu.pathFor(new TreePath(blockPath.getParentPath(), block), offset, sourcePositions));
                        if (path == null) {
                            return null;
                        }
                        lambdaBody = ((LambdaExpressionTree) path.getLeaf()).getBody();
                        bodyPos = (int) sourcePositions.getStartPosition(root, lambdaBody);
                        if (bodyPos >= offset) {
                            TokenSequence<JavaTokenId> ts = controller.getTokenHierarchy().tokenSequence(JavaTokenId.language());
                            ts.move(offset);
                            while (ts.movePrevious()) {
                                switch (ts.token().id()) {
                                    case WHITESPACE:
                                    case LINE_COMMENT:
                                    case BLOCK_COMMENT:
                                    case JAVADOC_COMMENT:
                                        break;
                                    case ARROW:
                                        scope = controller.getTrees().getScope(blockPath);
                                        scope = tu.reattributeTreeTo(block, scope, lambdaBody);
                                        return new Env(offset, prefix, controller, path, sourcePositions, scope);
                                    default:
                                        return null;
                                }
                            }
                        }
                        scope = controller.getTrees().getScope(blockPath);
                        scope = tu.reattributeTreeTo(block, scope, lambdaBody);
                        break;
                    }
                }
                blockPath = blockPath.getParentPath();
            }
            if (scope == null) {
                scope = controller.getTrees().getScope(new TreePath(path, lambdaBody));
                bodyPos = (int) sourcePositions.getStartPosition(root, lambdaBody);
                if (bodyPos >= offset) {
                    TokenSequence<JavaTokenId> ts = controller.getTokenHierarchy().tokenSequence(JavaTokenId.language());
                    ts.move(offset);
                    while (ts.movePrevious()) {
                        switch (ts.token().id()) {
                            case WHITESPACE:
                            case LINE_COMMENT:
                            case BLOCK_COMMENT:
                            case JAVADOC_COMMENT:
                                break;
                            case ARROW:
                                return new Env(offset, prefix, controller, path, sourcePositions, scope);
                            default:
                                return null;
                        }
                    }
                }
            }
            String bodyText = controller.getText().substring(bodyPos, upToOffset ? offset : (int) sourcePositions.getEndPosition(root, lambdaBody));
            final SourcePositions[] sp = new SourcePositions[1];
            final Tree body = bodyText.charAt(0) == '{' ? tu.parseStatement(bodyText, sp) : tu.parseExpression(bodyText, sp);
            final Tree fake = body instanceof ExpressionTree ? new ExpressionStatementTree() {
                @Override
                public Object accept(TreeVisitor v, Object p) {
                    return v.visitExpressionStatement(this, p);
                }

                @Override
                public ExpressionTree getExpression() {
                    return (ExpressionTree) body;
                }

                @Override
                public Tree.Kind getKind() {
                    return Tree.Kind.EXPRESSION_STATEMENT;
                }
            } : body;
            sourcePositions = new SourcePositionsImpl(fake, sourcePositions, sp[0], bodyPos, upToOffset ? offset : -1);
            path = tu.pathFor(new TreePath(path, fake), offset, sourcePositions);
            if (upToOffset && !(body instanceof ExpressionTree)) {
                Tree last = path.getLeaf();
                List<? extends StatementTree> stmts = null;
                switch (path.getLeaf().getKind()) {
                    case BLOCK:
                        stmts = ((BlockTree) path.getLeaf()).getStatements();
                        break;
                    case FOR_LOOP:
                        stmts = ((ForLoopTree) path.getLeaf()).getInitializer();
                        break;
                    case ENHANCED_FOR_LOOP:
                        stmts = Collections.singletonList(((EnhancedForLoopTree) path.getLeaf()).getStatement());
                        break;
                    case METHOD:
                        stmts = ((MethodTree) path.getLeaf()).getParameters();
                        break;
                    case SWITCH:
                        CaseTree lastCase = null;
                        for (CaseTree caseTree : ((SwitchTree) path.getLeaf()).getCases()) {
                            lastCase = caseTree;
                        }
                        if (lastCase != null) {
                            stmts = lastCase.getStatements();
                        }
                        break;
                    case CASE:
                        stmts = ((CaseTree) path.getLeaf()).getStatements();
                        break;
                }
                if (stmts != null) {
                    for (StatementTree st : stmts) {
                        if (sourcePositions.getEndPosition(root, st) <= offset) {
                            last = st;
                        }
                    }
                }
                scope = tu.reattributeTreeTo(body, scope, last);
            } else {
                scope = tu.reattributeTreeTo(body, scope, body);
            }
            return new Env(offset, prefix, controller, path, sourcePositions, scope);
        } else if (grandParent != null && TreeUtilities.CLASS_TREE_KINDS.contains(grandParent.getKind())
                && parent != null && parent.getKind() == Tree.Kind.VARIABLE && unwrapErrTree(((VariableTree) parent).getInitializer()) == tree) {
            if (tu.isEnum((ClassTree) grandParent)) {
                controller.toPhase(JavaSource.Phase.RESOLVED);
                return null;
            }
            controller.toPhase(withinAnonymousOrLocalClass(tu, path) ? JavaSource.Phase.RESOLVED : JavaSource.Phase.ELEMENTS_RESOLVED);
            Scope scope = controller.getTrees().getScope(path);
            final int initPos = (int) sourcePositions.getStartPosition(root, tree);
            String initText = controller.getText().substring(initPos, upToOffset ? offset : (int) sourcePositions.getEndPosition(root, tree));
            if (initText.length() > 0) {
                final SourcePositions[] sp = new SourcePositions[1];
                final ExpressionTree init = tu.parseVariableInitializer(initText, sp);
                final ExpressionStatementTree fake = new ExpressionStatementTree() {
                    @Override
                    public Object accept(TreeVisitor v, Object p) {
                        return v.visitExpressionStatement(this, p);
                    }

                    @Override
                    public ExpressionTree getExpression() {
                        return init;
                    }

                    @Override
                    public Tree.Kind getKind() {
                        return Tree.Kind.EXPRESSION_STATEMENT;
                    }
                };
                sourcePositions = new SourcePositionsImpl(fake, sourcePositions, sp[0], initPos, upToOffset ? offset : -1);
                path = tu.pathFor(new TreePath(pPath, fake), offset, sourcePositions);
                if (upToOffset && sp[0].getEndPosition(root, init) + initPos > offset) {
                    scope = tu.reattributeTreeTo(init, scope, path.getLeaf());
                } else {
                    tu.reattributeTree(init, scope);
                }
            }
            return new Env(offset, prefix, controller, path, sourcePositions, scope);
        } else if (parent != null && TreeUtilities.CLASS_TREE_KINDS.contains(parent.getKind()) && tree.getKind() == Tree.Kind.VARIABLE
                && ((VariableTree) tree).getInitializer() != null && orig == path
                && sourcePositions.getStartPosition(root, ((VariableTree) tree).getInitializer()) >= 0
                && sourcePositions.getStartPosition(root, ((VariableTree) tree).getInitializer()) <= offset) {
            controller.toPhase(withinAnonymousOrLocalClass(tu, path) ? JavaSource.Phase.RESOLVED : JavaSource.Phase.ELEMENTS_RESOLVED);
            tree = ((VariableTree) tree).getInitializer();
            Scope scope = controller.getTrees().getScope(new TreePath(path, tree));
            final int initPos = (int) sourcePositions.getStartPosition(root, tree);
            String initText = controller.getText().substring(initPos, offset);
            if (initText.length() > 0) {
                final SourcePositions[] sp = new SourcePositions[1];
                final ExpressionTree init = tu.parseVariableInitializer(initText, sp);
                final ExpressionStatementTree fake = new ExpressionStatementTree() {
                    @Override
                    public Object accept(TreeVisitor v, Object p) {
                        return v.visitExpressionStatement(this, p);
                    }

                    @Override
                    public ExpressionTree getExpression() {
                        return init;
                    }

                    @Override
                    public Tree.Kind getKind() {
                        return Tree.Kind.EXPRESSION_STATEMENT;
                    }
                };
                sourcePositions = new SourcePositionsImpl(fake, sourcePositions, sp[0], initPos, offset);
                path = tu.pathFor(new TreePath(path, fake), offset, sourcePositions);
                tu.reattributeTree(init, scope);
            }
            return new Env(offset, prefix, controller, path, sourcePositions, scope);
        }
        return null;
    }
    
    private static String whitespaceString(int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(' ');
        }
        return sb.toString();
    }

    private static class SourcePositionsImpl extends ErrorAwareTreeScanner<Void, Tree> implements SourcePositions {

        private final Tree root;
        private final SourcePositions original;
        private final SourcePositions modified;
        private final int startOffset;
        private final int endOffset;

        private boolean found;

        private SourcePositionsImpl(Tree root, SourcePositions original, SourcePositions modified, int startOffset, int endOffset) {
            this.root = root;
            this.original = original;
            this.modified = modified;
            this.startOffset = startOffset;
            this.endOffset = endOffset;
        }

        @Override
        public long getStartPosition(CompilationUnitTree compilationUnitTree, Tree tree) {
            if (tree == root) {
                return startOffset;
            }
            found = false;
            scan(root, tree);
            return found ? modified.getStartPosition(compilationUnitTree, tree) + startOffset : original.getStartPosition(compilationUnitTree, tree);
        }

        @Override
        public long getEndPosition(CompilationUnitTree compilationUnitTree, Tree tree) {
            if (tree == root) {
                return endOffset;
            }
            found = false;
            scan(root, tree);
            return found ? modified.getEndPosition(compilationUnitTree, tree) + startOffset : original.getEndPosition(compilationUnitTree, tree);
        }

        @Override
        public Void scan(Tree node, Tree p) {
            if (node == p) {
                found = true;
            } else {
                super.scan(node, p);
            }
            return null;
        }

    }

    private static boolean isCamelCasePrefix(String prefix) {
        if (prefix == null || prefix.length() < 2 || prefix.charAt(0) == '"') {
            return false;
        }
        for (int i = 1; i < prefix.length(); i++) {
            if (Character.isUpperCase(prefix.charAt(i))) {
                return true;
            }
        }
        return false;
    }

    private static boolean withinAnonymousOrLocalClass(TreeUtilities tu, TreePath path) {
        do {
            path = tu.getPathElementOfKind(TreeUtilities.CLASS_TREE_KINDS, path);
            if (path == null) {
                return false;
            }
            path = path.getParentPath();
            if (path.getLeaf().getKind() != Tree.Kind.COMPILATION_UNIT && !TreeUtilities.CLASS_TREE_KINDS.contains(path.getLeaf().getKind())) {
                return true;
            }
        } while (true);
    }

    static final class Env {

        private final int offset;
        private final String prefix;
        private final boolean isCamelCasePrefix;
        private final CompilationController controller;
        private final TreePath path;
        private final SourcePositions sourcePositions;
        private Scope scope;
        private ReferencesCount referencesCount;
        private Map<Name, Element> refs = null;
        private boolean afterExtends = false;
        private boolean insideNew = false;
        private boolean insideForEachExpression = false;
        private boolean insideClass = false;
        private Set<? extends TypeMirror> smartTypes = null;
        private Set<Element> excludes = null;
        private Set<String> kws = new HashSet<>();
        private boolean addSemicolon = false;
        private boolean checkAddSemicolon = true;
        private int assignToVarPos = -2;
        private boolean checkAccessibility = true;

        private Env(int offset, String prefix, CompilationController controller, TreePath path, SourcePositions sourcePositions, Scope scope) {
            this.offset = offset;
            this.prefix = prefix;
            this.isCamelCasePrefix = BaseTask.isCamelCasePrefix(prefix);
            this.controller = controller;
            this.path = path;
            this.sourcePositions = sourcePositions;
            this.scope = scope;
        }

        public int getOffset() {
            return offset;
        }

        public String getPrefix() {
            return prefix;
        }

        public boolean isCamelCasePrefix() {
            return isCamelCasePrefix;
        }

        public CompilationController getController() {
            return controller;
        }

        public CompilationUnitTree getRoot() {
            return path.getCompilationUnit();
        }

        public TreePath getPath() {
            return path;
        }

        public SourcePositions getSourcePositions() {
            return sourcePositions;
        }

        public Scope getScope() throws IOException {
            if (scope == null) {
                controller.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
                scope = controller.getTreeUtilities().scopeFor(offset);
            }
            return scope;
        }

        public ReferencesCount getReferencesCount() {
            if (referencesCount == null) {
                referencesCount = ReferencesCount.get(controller.getClasspathInfo());
            }
            return referencesCount;
        }

        public Map<Name, ? extends Element> getForwardReferences() {
            if (refs == null) {
                refs = new HashMap<>();
                for (Element ref : SourceUtils.getForwardReferences(path, offset, sourcePositions, controller.getTrees())) {
                    refs.put(ref.getSimpleName(), ref);
                }
            }
            return refs;
        }

        public boolean isAfterExtends() {
            return afterExtends;
        }

        public void afterExtends() {
            this.afterExtends = true;
        }

        public void insideForEachExpression() {
            this.insideForEachExpression = true;
        }

        public boolean isInsideForEachExpression() {
            return insideForEachExpression;
        }

        public void insideNew() {
            this.insideNew = true;
        }

        public boolean isInsideNew() {
            return insideNew;
        }

        public void insideClass() {
            this.insideClass = true;
        }

        public boolean isInsideClass() {
            return insideClass;
        }

        public void setSmartTypes(Set<? extends TypeMirror> smartTypes) throws IOException {
            this.smartTypes = smartTypes;
        }

        public Set<? extends TypeMirror> getSmartTypes() throws IOException {
            return smartTypes;
        }

        public void addToExcludes(Element toExclude) {
            if (toExclude != null) {
                if (excludes == null) {
                    excludes = new HashSet<>();
                }
                excludes.add(toExclude);
            }
        }

        public Set<? extends Element> getExcludes() {
            return excludes;
        }

        public void addExcludedKW(String kw) {
            if (kw != null) {
                kws.add(kw);
            }
        }

        public boolean isExcludedKW(String kw) {
            return kws.contains(kw);
        }

        public void skipAccessibilityCheck() {
            this.checkAccessibility = false;
        }

        public boolean isAccessible(Scope scope, Element member, TypeMirror type, boolean selectSuper) {
            if (!checkAccessibility) {
                return true;
            }
            if (type.getKind() != TypeKind.DECLARED) {
                return member.getModifiers().contains(PUBLIC);
            }
            if (getController().getTrees().isAccessible(scope, member, (DeclaredType) type)) {
                return true;
            }
            return selectSuper
                    && member.getModifiers().contains(PROTECTED) && !member.getModifiers().contains(STATIC)
                    && !member.getKind().isClass() && !member.getKind().isInterface()
                    && getController().getTrees().isAccessible(scope, (TypeElement) ((DeclaredType) type).asElement())
                    && (member.getKind() != METHOD
                    || getController().getElementUtilities().getImplementationOf((ExecutableElement) member, (TypeElement) ((DeclaredType) type).asElement()) == member);
        }

        public boolean addSemicolon() {
            if (checkAddSemicolon) {
                TreePath tp = getPath();
                Tree tree = tp.getLeaf();
                if (tree.getKind() == Tree.Kind.IDENTIFIER || tree.getKind() == Tree.Kind.PRIMITIVE_TYPE) {
                    tp = tp.getParentPath();
                    if (tp.getLeaf().getKind() == Tree.Kind.VARIABLE && ((VariableTree) tp.getLeaf()).getType() == tree) {
                        addSemicolon = true;
                    }
                }
                if (tp.getLeaf().getKind() == Tree.Kind.MEMBER_SELECT
                        || (tp.getLeaf().getKind() == Tree.Kind.METHOD_INVOCATION && ((MethodInvocationTree) tp.getLeaf()).getMethodSelect() == tree)
                        || tp.getLeaf().getKind() == Tree.Kind.VARIABLE) {
                    tp = tp.getParentPath();
                }
                if (tp.getLeaf().getKind() == Tree.Kind.EXPRESSION_STATEMENT
                        && tp.getParentPath().getLeaf().getKind() != Tree.Kind.LAMBDA_EXPRESSION
                        || tp.getLeaf().getKind() == Tree.Kind.BLOCK
                        || tp.getLeaf().getKind() == Tree.Kind.RETURN) {
                    addSemicolon = true;
                }
                checkAddSemicolon = false;
            }
            return addSemicolon;
        }

        public int assignToVarPos() {
            if (assignToVarPos < -1) {
                TreePath tp = getPath();
                Tree tree = tp.getLeaf();
                if (tp.getLeaf().getKind() == Tree.Kind.MEMBER_SELECT
                        || (tp.getLeaf().getKind() == Tree.Kind.METHOD_INVOCATION && ((MethodInvocationTree) tp.getLeaf()).getMethodSelect() == tree)) {
                    tp = tp.getParentPath();
                }
                if (tp.getLeaf().getKind() == Tree.Kind.EXPRESSION_STATEMENT) {
                    assignToVarPos = getController().getSnapshot().getOriginalOffset((int) getSourcePositions().getStartPosition(getRoot(), tree));
                } else if (tp.getLeaf().getKind() == Tree.Kind.BLOCK) {
                    assignToVarPos = getController().getSnapshot().getOriginalOffset(offset);
                } else {
                    assignToVarPos = -1;
                }
            }
            return assignToVarPos;
        }
    }
}
