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

import com.sun.source.tree.ImportTree;
import com.sun.source.tree.ArrayAccessTree;
import com.sun.source.tree.AssertTree;
import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.ConditionalExpressionTree;
import com.sun.source.tree.DoWhileLoopTree;
import com.sun.source.tree.EnhancedForLoopTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.ForLoopTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.IfTree;
import com.sun.source.tree.InstanceOfTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.NewArrayTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.ParameterizedTypeTree;
import com.sun.source.tree.ParenthesizedTree;
import com.sun.source.tree.ReturnTree;
import com.sun.source.tree.Scope;
import com.sun.source.tree.SwitchTree;
import com.sun.source.tree.SynchronizedTree;
import com.sun.source.tree.ThrowTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.Tree.Kind;
import com.sun.source.tree.TypeParameterTree;
import com.sun.source.tree.UnaryTree;
import com.sun.source.tree.VariableTree;
import com.sun.source.tree.WhileLoopTree;
import com.sun.source.util.SourcePositions;
import com.sun.source.util.TreePath;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ArrayType;
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.ElementFilter;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.java.source.CompilationInfo;
import org.netbeans.api.java.source.TreeUtilities;
import org.netbeans.modules.refactoring.java.plugins.JavaPluginUtils;

/**
 * Copy of org.netbeans.modules.java.hints.errors.CreateElementUtilities
 * @author Jan Lahoda
 */
public final class CreateElementUtilities {

    private CreateElementUtilities() {}

    public static List<? extends TypeMirror> resolveType(Set<ElementKind> types, CompilationInfo info, TreePath currentPath, Tree unresolved, int offset, TypeMirror[] typeParameterBound, int[] numTypeParameters) {
        switch (currentPath.getLeaf().getKind()) {
            case METHOD:
                return computeMethod(types, info, currentPath, typeParameterBound ,unresolved, offset);
            case MEMBER_SELECT:
                return computeMemberSelect(types, info, currentPath, unresolved, offset);
            case ASSIGNMENT:
                return computeAssignment(types, info, currentPath, unresolved, offset);
            case ENHANCED_FOR_LOOP:
                return computeEnhancedForLoop(types, info, currentPath, unresolved, offset);
            case ARRAY_ACCESS:
                return computeArrayAccess(types, info, currentPath, unresolved, offset);
            case VARIABLE:
                return computeVariableDeclaration(types, info, currentPath, unresolved, offset);
            case ASSERT:
                return computeAssert(types, info, currentPath, unresolved, offset);
            case PARENTHESIZED:
                return computeParenthesis(types, info, currentPath, unresolved, offset);            
            case DO_WHILE_LOOP:
                return computePrimitiveType(types, info, ((DoWhileLoopTree) currentPath.getLeaf()).getCondition(), unresolved, TypeKind.BOOLEAN);
            case FOR_LOOP:
                return computePrimitiveType(types, info, ((ForLoopTree) currentPath.getLeaf()).getCondition(), unresolved, TypeKind.BOOLEAN);
            case IF:
                return computePrimitiveType(types, info, ((IfTree) currentPath.getLeaf()).getCondition(), unresolved, TypeKind.BOOLEAN);
            case WHILE_LOOP:
                return computePrimitiveType(types, info, ((WhileLoopTree) currentPath.getLeaf()).getCondition(), unresolved, TypeKind.BOOLEAN);
            case SYNCHRONIZED:
                return computeReferenceType(types, info, ((SynchronizedTree) currentPath.getLeaf()).getExpression(), unresolved, "java.lang.Object");
            case THROW:
                return computeReferenceType(types, info, ((ThrowTree) currentPath.getLeaf()).getExpression(), unresolved, "java.lang.Exception");
            case INSTANCE_OF:
                return computeReferenceType(types, info, ((InstanceOfTree) currentPath.getLeaf()).getExpression(), unresolved, "java.lang.Object");
            case SWITCH:
                //TODO: should consider also values in the cases?:
                return computePrimitiveType(types, info, ((SwitchTree) currentPath.getLeaf()).getExpression(), unresolved, TypeKind.INT);
            case EXPRESSION_STATEMENT:
                return Collections.singletonList(info.getTypes().getNoType(TypeKind.VOID));

            case RETURN:
                return computeReturn(types, info, currentPath, unresolved, offset);
            case TYPE_PARAMETER:
                return computeTypeParameter(types, info, currentPath, unresolved, offset);
            case PARAMETERIZED_TYPE:
                return computeParametrizedType(types, info, currentPath, unresolved, offset, typeParameterBound, numTypeParameters);
            case ANNOTATION_TYPE:
            case CLASS:
            case ENUM:
            case INTERFACE:
                return computeClass(types, info, currentPath, unresolved, offset);
                
            case CONDITIONAL_EXPRESSION:
                return computeConditionalExpression(types, info, currentPath, unresolved, offset);
                
            case NEW_ARRAY:
                return computeNewArray(types, info, currentPath, unresolved, offset);
                
            case METHOD_INVOCATION:
                return computeMethodInvocation(types, info, currentPath, unresolved, offset);
                
            case NEW_CLASS:
                return computeNewClass(types, info, currentPath, unresolved, offset);
                
            case POSTFIX_INCREMENT:
            case POSTFIX_DECREMENT:
            case PREFIX_INCREMENT:
            case PREFIX_DECREMENT:
            case UNARY_PLUS:
            case UNARY_MINUS:
            case BITWISE_COMPLEMENT:
            case LOGICAL_COMPLEMENT:
                return computeUnary(types, info, currentPath, unresolved, offset);

            case MULTIPLY:
            case DIVIDE:
            case REMAINDER:
            case PLUS:
            case MINUS:
            case LEFT_SHIFT:
            case RIGHT_SHIFT:
            case UNSIGNED_RIGHT_SHIFT:
            case LESS_THAN:
            case GREATER_THAN:
            case LESS_THAN_EQUAL:
            case GREATER_THAN_EQUAL:
            case EQUAL_TO:
            case NOT_EQUAL_TO:
            case AND:
            case XOR:
            case OR:
            case CONDITIONAL_AND:
            case CONDITIONAL_OR:
                return computeBinaryOperator(types, info, currentPath, unresolved, offset);
                
            case MULTIPLY_ASSIGNMENT:
            case DIVIDE_ASSIGNMENT:
            case REMAINDER_ASSIGNMENT:
            case PLUS_ASSIGNMENT:
            case MINUS_ASSIGNMENT:
            case LEFT_SHIFT_ASSIGNMENT:
            case RIGHT_SHIFT_ASSIGNMENT:
            case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
            case AND_ASSIGNMENT:
            case XOR_ASSIGNMENT:
            case OR_ASSIGNMENT:
                //XXX: return computeCompoundAssignment(types, info, currentPath, unresolved, offset);
                return null;
                        
            case ARRAY_TYPE:
                return computeArrayType(types, info, currentPath, unresolved, offset);

            case IMPORT:
                return computeImport(types, info, currentPath, unresolved, offset);
                
            case BLOCK:
            case BREAK:
            case CATCH:
            case COMPILATION_UNIT:
            case CONTINUE:
            case IDENTIFIER:
            case TYPE_CAST:
            case TRY:
            case EMPTY_STATEMENT:
            case PRIMITIVE_TYPE:
            case LABELED_STATEMENT:
            case MODIFIERS:
            case ERRONEOUS:
            case OTHER:
            case INT_LITERAL:
            case LONG_LITERAL:
            case FLOAT_LITERAL:
            case DOUBLE_LITERAL:
            case BOOLEAN_LITERAL:
            case CHAR_LITERAL:
            case STRING_LITERAL:
            case NULL_LITERAL:
                //ignored:
                return null;
                
            case CASE:
            case ANNOTATION:
            case UNBOUNDED_WILDCARD:
            case EXTENDS_WILDCARD:
            case SUPER_WILDCARD:
                //XXX: currently unhandled
                return null;
                
            default:
                //should not happen unless set of Tree.Kind changes:
                return null;
        }
    }
    
    private static List<? extends TypeMirror> computeBinaryOperator(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        BinaryTree bt = (BinaryTree) parent.getLeaf();
        TreePath typeToResolve = null;
        
        if (bt.getLeftOperand() == error) {
            typeToResolve = new TreePath(parent, bt.getRightOperand());
        }
        
        if (bt.getRightOperand() == error) {
            typeToResolve = new TreePath(parent, bt.getLeftOperand());
        }
        
        if (typeToResolve != null) {
            TypeMirror resolvedType = info.getTrees().getTypeMirror(typeToResolve);
            
            if (resolvedType != null) {
                types.add(ElementKind.PARAMETER);
                types.add(ElementKind.LOCAL_VARIABLE);
                types.add(ElementKind.FIELD);
                
                if (resolvedType.getKind() == TypeKind.ERROR || resolvedType.getKind() == TypeKind.OTHER) {
                    return resolveType(types, info, parent.getParentPath(), bt, offset, null, null);
                }
                
                return Collections.singletonList(resolvedType);
            }
        }
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeMethod(Set<ElementKind> types, CompilationInfo info, TreePath parent, TypeMirror[] typeParameterBound, Tree error, int offset) {
        //class or field:
        //check the error is in the body:
        //#92419: check for abstract method/method without body:
        MethodTree mt = (MethodTree) parent.getLeaf();
        
        if (mt.getReturnType() == error) {
            types.add(ElementKind.CLASS);
            types.add(ElementKind.INTERFACE);
            types.add(ElementKind.ENUM);
        }

        List<? extends ExpressionTree> throwList = mt.getThrows();
	if (throwList != null && !throwList.isEmpty()) {
            for (ExpressionTree t : throwList) {
                if (t == error) {
                    types.add(ElementKind.CLASS);
                    typeParameterBound[0] = info.getElements().getTypeElement("java.lang.Exception").asType();
                    break;
                }
            }
	}
        
        if (mt.getBody() == null) {
            return null;
        }
        
        try {
            Document doc = info.getDocument();
            
            if (doc != null) {//XXX
                int bodyStart = findBodyStart(parent.getLeaf(), info.getCompilationUnit(), info.getTrees().getSourcePositions(), doc);
                int bodyEnd   = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), parent.getLeaf());

                types.add(ElementKind.PARAMETER);
                types.add(ElementKind.LOCAL_VARIABLE);
                types.add(ElementKind.FIELD);

                if (bodyStart <= offset && offset <= bodyEnd)
                    return Collections.singletonList(info.getElements().getTypeElement("java.lang.Object").asType());
            }
        } catch (IOException ex) {
            Logger.getLogger("global").log(Level.INFO, ex.getMessage(), ex);
        }
        
        return null;
    }
    
    private static int findBodyStartImpl(Tree cltree, CompilationUnitTree cu, SourcePositions positions, Document doc) {
        int start = (int)positions.getStartPosition(cu, cltree);
        int end   = (int)positions.getEndPosition(cu, cltree);
        
        if (start == (-1) || end == (-1)) {
            return -1;
        }
        
        if (start > doc.getLength() || end > doc.getLength()) {
            return (-1);
        }
        
        try {
            String text = doc.getText(start, end - start);
            
            int index = text.indexOf('{');
            
            if (index == (-1)) {
                return -1;
//                throw new IllegalStateException("Should NEVER happen.");
            }
            
            return start + index;
        } catch (BadLocationException e) {
            LOG.log(Level.INFO, null, e);
        }
        
        return (-1);
    }
    private static final Logger LOG = Logger.getLogger(CreateElementUtilities.class.getName());
    
    public static int findBodyStart(final Tree cltree, final CompilationUnitTree cu, final SourcePositions positions, final Document doc) {
        Kind kind = cltree.getKind();
        if (!TreeUtilities.CLASS_TREE_KINDS.contains(kind) && kind != Kind.METHOD)
            throw new IllegalArgumentException("Unsupported kind: "+ kind);
        final int[] result = new int[1];
        
        doc.render(new Runnable() {
            public void run() {
                result[0] = findBodyStartImpl(cltree, cu, positions, doc);
            }
        });
        
        return result[0];
    }
    
    private static List<? extends TypeMirror> computeMemberSelect(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        //class or field:
        MemberSelectTree ms = (MemberSelectTree) parent.getLeaf();
        final TypeElement jlObject = info.getElements().getTypeElement("java.lang.Object");
        
        if (   jlObject != null //may happen if the platform is broken
            && !"class".equals(ms.getIdentifier().toString())) {//we obviously should not propose "Create Field" for unknown.class:
            types.add(ElementKind.FIELD);
            types.add(ElementKind.CLASS);
            return Collections.singletonList(jlObject.asType());
        }
        
        return null;
    }
    
    /**
     *
     * @param info context {@link CompilationInfo}
     * @param iterable tested {@link TreePath}
     * @return generic type of an {@link Iterable} or {@link ArrayType} at a TreePath
     */
    public static TypeMirror getIterableGenericType(CompilationInfo info, TreePath iterable) {
        TypeElement iterableElement = info.getElements().getTypeElement("java.lang.Iterable"); //NOI18N
        if (iterableElement == null) {
            return null;
        }
        TypeMirror iterableType = info.getTrees().getTypeMirror(iterable);
        if (iterableType == null) {
            return null;
        }
        TypeMirror designedType = null;
        if (iterableType.getKind() == TypeKind.DECLARED) {
            DeclaredType declaredType = (DeclaredType) iterableType;
            if (!info.getTypes().isSubtype(info.getTypes().erasure(declaredType), info.getTypes().erasure(iterableElement.asType()))) {
                return null;
            }
            ExecutableElement iteratorMethod = (ExecutableElement) iterableElement.getEnclosedElements().get(0);
            ExecutableType iteratorMethodType = (ExecutableType) info.getTypes().asMemberOf(declaredType, iteratorMethod);
            List<? extends TypeMirror> typeArguments = ((DeclaredType) iteratorMethodType.getReturnType()).getTypeArguments();
            if (!typeArguments.isEmpty()) {
                designedType = typeArguments.get(0);
            } else {
                TypeElement jlObject = info.getElements().getTypeElement("java.lang.Object");

                if (jlObject != null) {
                    designedType = jlObject.asType();
                }
            }
        } else if (iterableType.getKind() == TypeKind.ARRAY) {
            designedType = ((ArrayType) iterableType).getComponentType();
        }
        if (designedType == null) {
            return null;
        }
        return JavaPluginUtils.resolveCapturedType(info, designedType);
    }
    
    private static List<? extends TypeMirror> computeAssignment(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        AssignmentTree at = (AssignmentTree) parent.getLeaf();
        TypeMirror     type = null;
        
        if (at.getVariable() == error) {
            type = info.getTrees().getTypeMirror(new TreePath(parent, at.getExpression()));

            if (type != null) {
                //anonymous class?
                type = JavaPluginUtils.convertIfAnonymous(type);

                if (type.getKind() == TypeKind.EXECUTABLE) {
                    //TODO: does not actualy work, attempt to solve situations like:
                    //t = Collections.emptyList()
                    //t = Collections.<String>emptyList();
                    //see also testCreateFieldMethod1 and testCreateFieldMethod2 tests:
                    type = ((ExecutableType) type).getReturnType();
                }
            }
        }
        
        if (at.getExpression() == error) {
            type = info.getTrees().getTypeMirror(new TreePath(parent, at.getVariable()));
        }
        
        //class or field:
        if (type == null) {
            return null;
        }
        
        types.add(ElementKind.PARAMETER);
        types.add(ElementKind.LOCAL_VARIABLE);
        types.add(ElementKind.FIELD);
        
        return Collections.singletonList(type);
    }
    
    private static List<? extends TypeMirror> computeEnhancedForLoop(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        EnhancedForLoopTree efl = (EnhancedForLoopTree) parent.getLeaf();
        
        if (efl.getExpression() != error) {
            return null;
        }
                        
        TypeMirror argument = info.getTrees().getTypeMirror(new TreePath(new TreePath(parent, efl.getVariable()), efl.getVariable().getType()));
        
        if (argument == null)
            return null;
        
        if (argument.getKind().isPrimitive()) {
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);

            return Collections.singletonList(info.getTypes().getArrayType(argument));
        }
        
        TypeElement iterable = info.getElements().getTypeElement("java.lang.Iterable"); //NOI18N
        if (iterable == null) {
            return null;
        }
        
        types.add(ElementKind.PARAMETER);
        types.add(ElementKind.LOCAL_VARIABLE);
        types.add(ElementKind.FIELD);
        
        return Collections.singletonList(info.getTypes().getDeclaredType(iterable, argument));
    }
    
    private static List<? extends TypeMirror> computeArrayAccess(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        ArrayAccessTree aat = (ArrayAccessTree) parent.getLeaf();
        
        if (aat.getExpression() == error) {
            TreePath parentParent = parent.getParentPath();
            List<? extends TypeMirror> upperTypes = resolveType(types, info, parentParent, aat, offset, null, null);
            
            if (upperTypes == null) {
                return null;
            }
            
            List<TypeMirror> arrayTypes = new ArrayList<TypeMirror>();
            
            for (TypeMirror tm : upperTypes) {
                if (tm == null)
                    continue;
                switch (tm.getKind()) {
                    case VOID:
                    case EXECUTABLE:
                    case WILDCARD:
                    case PACKAGE:
                        continue;
                }
                
                arrayTypes.add(info.getTypes().getArrayType(tm));
            }
            
            if (arrayTypes.isEmpty())
                return null;
            
            return arrayTypes;
        }
        
        if (aat.getIndex() == error) {
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);
            
            return Collections.singletonList(info.getTypes().getPrimitiveType(TypeKind.INT));
        }
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeVariableDeclaration(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        VariableTree vt = (VariableTree) parent.getLeaf();
        
        if (vt.getInitializer() == error) {
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);
            
            return Collections.singletonList(info.getTrees().getTypeMirror(new TreePath(parent, vt.getType())));
        }
        
        TreePath context = parent.getParentPath();
        if (vt.getType() != error || context == null) {
            return null;
        }

        switch (context.getLeaf().getKind()) {
            case ENHANCED_FOR_LOOP:
                ExpressionTree iterableTree = ((EnhancedForLoopTree) context.getLeaf()).getExpression();
                TreePath iterablePath = new TreePath(context, iterableTree);
                TypeMirror type = getIterableGenericType(info, iterablePath);
                types.add(ElementKind.LOCAL_VARIABLE);
                return Collections.singletonList(type);
            default:
                types.add(ElementKind.CLASS);
                return Collections.<TypeMirror>emptyList();
        }
    }
    
    private static List<? extends TypeMirror> computeAssert(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        AssertTree at = (AssertTree) parent.getLeaf();
        
        types.add(ElementKind.PARAMETER);
        types.add(ElementKind.LOCAL_VARIABLE);
        types.add(ElementKind.FIELD);
        
        if (at.getCondition() == error) {
            return Collections.singletonList(info.getTypes().getPrimitiveType(TypeKind.BOOLEAN));
        }
        
        if (at.getDetail() == error) {
            return Collections.singletonList(info.getElements().getTypeElement("java.lang.Object").asType());
        }
        
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeParenthesis(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        ParenthesizedTree pt = (ParenthesizedTree) parent.getLeaf();
        
        if (pt.getExpression() != error) {
            return null;
        }
        
        TreePath parentParent = parent.getParentPath();
        List<? extends TypeMirror> upperTypes = resolveType(types, info, parentParent, pt, offset, null, null);
        
        if (upperTypes == null) {
            return null;
        }
        
        return upperTypes;
    }
    
    private static List<? extends TypeMirror> computeConditionalExpression(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        ConditionalExpressionTree cet = (ConditionalExpressionTree) parent.getLeaf();
        
        if (cet.getCondition() == error) {
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);
            
            return Collections.singletonList(info.getTypes().getPrimitiveType(TypeKind.BOOLEAN));
        }
        
        if (cet.getTrueExpression() == error || cet.getFalseExpression() == error) {
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);
            
            return resolveType(types, info, parent.getParentPath(), cet, offset, null, null);
        }
        
        return null;
    }
    
    private static List<? extends TypeMirror> computePrimitiveType(Set<ElementKind> types, CompilationInfo info, Tree expression, Tree error, TypeKind kind) {
        if (expression == error) {
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);
            
            return Collections.singletonList(info.getTypes().getPrimitiveType(kind));
        }
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeReferenceType(Set<ElementKind> types, CompilationInfo info, Tree expression, Tree error, String type) {
        if (expression == error) {
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);
            
            return Collections.singletonList(info.getElements().getTypeElement(type).asType());
        }
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeImport(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        ImportTree tree = (ImportTree) parent.getLeaf();

        if (tree.getQualifiedIdentifier() == error) {
            types.add(ElementKind.ANNOTATION_TYPE);
            types.add(ElementKind.CLASS);
            types.add(ElementKind.ENUM);
            types.add(ElementKind.INTERFACE);
            
            return Collections.singletonList(info.getElements().getTypeElement("java.lang.Object").asType());
        }

        return null;
    }

    private static List<? extends TypeMirror> computeUnary(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        UnaryTree tree = (UnaryTree) parent.getLeaf();
        
        if (tree.getExpression() == error) {
            List<? extends TypeMirror> parentTypes = resolveType(types, info, parent.getParentPath(), tree, offset, null, null);
            
            if (parentTypes != null) {
                //may contain only "void", ignore:
                if (parentTypes.size() != 1) {
                    return parentTypes;
                }
                if (parentTypes.get(0).getKind() != TypeKind.VOID) {
                    return parentTypes;
                }
            }
            
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);

            return Collections.singletonList(info.getTypes().getPrimitiveType(TypeKind.INT));
        }
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeReturn(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        ReturnTree rt = (ReturnTree) parent.getLeaf();
        
        if (rt.getExpression() == error) {
            TreePath method = findMethod(parent);
            
            if (method == null) {
                return null;
            }
            
            Element el = info.getTrees().getElement(method);
            
            if (el == null || el.getKind() != ElementKind.METHOD) {
                return null;
            }
            
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);
            
            return Collections.singletonList(((ExecutableElement) el).getReturnType());
        }
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeTypeParameter(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        TypeParameterTree tpt = (TypeParameterTree) parent.getLeaf();
        
        for (Tree t : tpt.getBounds()) {
            if (t == error) {
                types.add(ElementKind.CLASS); //XXX: class/interface/enum/annotation?
                return null;
            }
        }
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeParametrizedType(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset, TypeMirror[] typeParameterBound, int[] numTypeParameters) {
        ParameterizedTypeTree ptt = (ParameterizedTypeTree) parent.getLeaf();
        
        if (ptt.getType() == error) {
            Tree gpt = parent.getParentPath().getLeaf();
            if (TreeUtilities.CLASS_TREE_KINDS.contains(gpt.getKind()) && ((ClassTree)gpt).getExtendsClause() == ptt) {
                types.add(ElementKind.CLASS);
            } else if (TreeUtilities.CLASS_TREE_KINDS.contains(gpt.getKind()) && ((ClassTree)gpt).getImplementsClause().contains(ptt)) {
                types.add(ElementKind.INTERFACE);
            } else {
                types.add(ElementKind.CLASS);
                types.add(ElementKind.INTERFACE);
            }
            
            if (numTypeParameters != null) {
                numTypeParameters[0] = ptt.getTypeArguments().size();
            }
            return null;
        }
        
        TypeMirror resolved = info.getTrees().getTypeMirror(parent);
        DeclaredType resolvedDT = null;
        
        if (resolved != null && resolved.getKind() == TypeKind.DECLARED) {
            resolvedDT = (DeclaredType) resolved;
        }
        
        int index = 0;
        
        for (Tree t : ptt.getTypeArguments()) {
            if (t == error) {
                if (resolvedDT != null && typeParameterBound != null) {
                    List<? extends TypeMirror> typeArguments = ((DeclaredType) resolvedDT.asElement().asType()).getTypeArguments();
                    
                    if (typeArguments.size() > index) {
                        typeParameterBound[0] = ((TypeVariable) typeArguments.get(index)).getUpperBound();
                    }
                }
                
                types.add(ElementKind.CLASS); //XXX: class/interface/enum/annotation?
                return null;
            }
            
            index++;
        }
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeClass(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        ClassTree ct = (ClassTree) parent.getLeaf();
        
        if (ct.getExtendsClause() == error) {
            types.add(ElementKind.CLASS);
            return null;
        }
        
        for (Tree t : ct.getImplementsClause()) {
            if (t == error) {
                types.add(ElementKind.INTERFACE);
                return null;
            }
        }
        
        //XXX: annotation types...
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeNewArray(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        NewArrayTree nat = (NewArrayTree) parent.getLeaf();
        
        if (nat.getType() == error) {
            types.add(ElementKind.CLASS);
            types.add(ElementKind.ENUM);
            types.add(ElementKind.INTERFACE);
            
            return null;
        }
        
        for (Tree dimension : nat.getDimensions()) {
            if (dimension == error) {
                types.add(ElementKind.PARAMETER);
                types.add(ElementKind.LOCAL_VARIABLE);
                types.add(ElementKind.FIELD);
                
                return Collections.singletonList(info.getTypes().getPrimitiveType(TypeKind.INT));
            }
        }
        
        for (Tree init : nat.getInitializers()) {
            if (init == error) {
                TypeMirror whole = info.getTrees().getTypeMirror(parent);
                
                if (whole == null || whole.getKind() != TypeKind.ARRAY)
                    return null;
                
                types.add(ElementKind.PARAMETER);
                types.add(ElementKind.LOCAL_VARIABLE);
                types.add(ElementKind.FIELD);
                
                return Collections.singletonList(((ArrayType) whole).getComponentType());
            }
        }
        
        return null;
    }
    
    private static List<? extends TypeMirror> computeMethodInvocation(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        MethodInvocationTree nat = (MethodInvocationTree) parent.getLeaf();
        boolean errorInRealArguments = false;
        
        for (Tree param : nat.getArguments()) {
            errorInRealArguments |= param == error;
        }
        
        if (errorInRealArguments) {
            List<TypeMirror> proposedTypes = new ArrayList<TypeMirror>();
            int[] proposedIndex = new int[1];
            List<ExecutableElement> ee = fuzzyResolveMethodInvocation(info, parent, proposedTypes, proposedIndex);
            
            if (ee.isEmpty()) { //cannot be resolved
                return null;
            }
            
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);
            
            return proposedTypes;
        }
        
        return null;
    }
    
    /**
     * @since 2.12
     */
    public static @NonNull List<ExecutableElement> fuzzyResolveMethodInvocation(CompilationInfo info, TreePath path, List<TypeMirror> proposed, int[] index) {
        assert path.getLeaf().getKind() == Kind.METHOD_INVOCATION || path.getLeaf().getKind() == Kind.NEW_CLASS;
        
        if (path.getLeaf().getKind() == Kind.METHOD_INVOCATION) {
            List<TypeMirror> actualTypes = new LinkedList<TypeMirror>();
            MethodInvocationTree mit = (MethodInvocationTree) path.getLeaf();

            for (Tree a : mit.getArguments()) {
                TreePath tp = new TreePath(path, a);
                actualTypes.add(info.getTrees().getTypeMirror(tp));
            }

            String methodName;
            TypeMirror on;

            switch (mit.getMethodSelect().getKind()) {
                case IDENTIFIER:
                    Scope s = info.getTrees().getScope(path);
                    TypeElement enclosingClass = s.getEnclosingClass();
                    on = enclosingClass != null ? enclosingClass.asType() : null;
                    methodName = ((IdentifierTree) mit.getMethodSelect()).getName().toString();
                    break;
                case MEMBER_SELECT:
                    on = info.getTrees().getTypeMirror(new TreePath(path, ((MemberSelectTree) mit.getMethodSelect()).getExpression()));
                    methodName = ((MemberSelectTree) mit.getMethodSelect()).getIdentifier().toString();
                    break;
                default:
                    throw new IllegalStateException();
            }

            if (on == null || on.getKind() != TypeKind.DECLARED) {
                return Collections.emptyList();
            }
            
            return resolveMethod(info, actualTypes, (DeclaredType) on, false, false, methodName, proposed, index);
        }
        
        if (path.getLeaf().getKind() == Kind.NEW_CLASS) {
            List<TypeMirror> actualTypes = new LinkedList<TypeMirror>();
            NewClassTree nct = (NewClassTree) path.getLeaf();

            for (Tree a : nct.getArguments()) {
                TreePath tp = new TreePath(path, a);
                actualTypes.add(info.getTrees().getTypeMirror(tp));
            }

            TypeMirror on = info.getTrees().getTypeMirror(new TreePath(path, nct.getIdentifier()));
            
            if (on == null || on.getKind() != TypeKind.DECLARED) {
                return Collections.emptyList();
            }
            
            return resolveMethod(info, actualTypes, (DeclaredType) on, false, true, null, proposed, index);
        }
        
        return Collections.emptyList();
    }
    
    private static List<ExecutableElement> resolveMethod(CompilationInfo info, List<TypeMirror> foundTypes, DeclaredType on, boolean statik, boolean constr, String name, List<TypeMirror> candidateTypes, int[] index) {
        if (on.asElement() == null) return Collections.emptyList();
        
        List<ExecutableElement> found = new LinkedList<ExecutableElement>();
        
        OUTER:
        for (ExecutableElement ee : execsIn(info, (TypeElement) on.asElement(), constr, name)) {
            TypeMirror currType = ((TypeElement) ee.getEnclosingElement()).asType();
            if (!info.getTypes().isSubtype(on, currType) && !on.asElement().equals(((DeclaredType)currType).asElement())) //XXX: fix for #132627, a clearer fix may exist
                continue;
            if (ee.getParameters().size() == foundTypes.size() /*XXX: variable arg count*/) {
                TypeMirror innerCandidate = null;
                int innerIndex = -1;
                ExecutableType et = (ExecutableType) info.getTypes().asMemberOf(on, ee);
                Iterator<? extends TypeMirror> formal = et.getParameterTypes().iterator();
                Iterator<? extends TypeMirror> actual = foundTypes.iterator();
                boolean mismatchFound = false;
                int i = 0;

                while (formal.hasNext() && actual.hasNext()) {
                    TypeMirror currentFormal = formal.next();
                    TypeMirror currentActual = actual.next();

                    if (!info.getTypes().isAssignable(currentActual, currentFormal) || currentActual.getKind() == TypeKind.ERROR) {
                        if (mismatchFound) {
                            //only one mismatch supported:
                            continue OUTER;
                        }
                        mismatchFound = true;
                        innerCandidate = currentFormal;
                        innerIndex = i;
                    }

                    i++;
                }

                if (mismatchFound) {
                    if (candidateTypes.isEmpty()) {
                        index[0] = innerIndex;
                        candidateTypes.add(innerCandidate);
                        found.add(ee);
                    } else {
                        //see testFuzzyResolveConstructor2:
                        if (index[0] == innerIndex) {
                            boolean add = true;
                            for (TypeMirror tm : candidateTypes) {
                                if (info.getTypes().isSameType(tm, innerCandidate)) {
                                    add = false;
                                    break;
                                }
                            }
                            if (add) {
                                candidateTypes.add(innerCandidate);
                                found.add(ee);
                            }
                        }
                    }
                }
            }
        }

        return found;
    }
    
    private static Iterable<ExecutableElement> execsIn(CompilationInfo info, TypeElement e, boolean constr, String name) {
        if (constr) {
            return ElementFilter.constructorsIn(info.getElements().getAllMembers(e));
        }
        
        List<ExecutableElement> result = new LinkedList<ExecutableElement>();
        
        for (ExecutableElement ee : ElementFilter.methodsIn(info.getElements().getAllMembers(e))) {
            if (name.equals(ee.getSimpleName().toString())) {
                result.add(ee);
            }
        }
        
        return result;
    }
    
    private static List<? extends TypeMirror> computeNewClass(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        NewClassTree nct = (NewClassTree) parent.getLeaf();
        boolean errorInRealArguments = false;
        
        for (Tree param : nct.getArguments()) {
            errorInRealArguments |= param == error;
        }
        
        if (errorInRealArguments) {
            List<TypeMirror> proposedTypes = new ArrayList<TypeMirror>();
            int[] proposedIndex = new int[1];
            List<ExecutableElement> ee = fuzzyResolveMethodInvocation(info, parent, proposedTypes, proposedIndex);
            
            if (ee.isEmpty()) { //cannot be resolved
                return null;
            }
            
            types.add(ElementKind.PARAMETER);
            types.add(ElementKind.LOCAL_VARIABLE);
            types.add(ElementKind.FIELD);
            
            return proposedTypes;
        }

        Tree id = nct.getIdentifier();

        if (id.getKind() == Kind.PARAMETERIZED_TYPE) {
            id = ((ParameterizedTypeTree) id).getType();
        }

        if (id == error) {
            return resolveType(EnumSet.noneOf(ElementKind.class), info, parent.getParentPath(), nct, offset, null, null);
        }
        
        return null;
    }

    private static List<? extends TypeMirror> computeArrayType(Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
        types.add(ElementKind.CLASS);

        return Collections.singletonList(info.getElements().getTypeElement("java.lang.Object").asType());
    }
    
    private static final Set<Kind> STOP_LOOKING_FOR_METHOD = EnumSet.of(Kind.METHOD, Kind.ANNOTATION_TYPE, Kind.CLASS, Kind.ENUM, Kind.INTERFACE, Kind.COMPILATION_UNIT);
            
    private static TreePath findMethod(TreePath tp) {
        while (!STOP_LOOKING_FOR_METHOD.contains(tp.getLeaf().getKind())) {
            tp = tp.getParentPath();
        }
        
        if (tp.getLeaf().getKind() == Kind.METHOD) {
            return tp;
        }
        
        return null;
    }
    
}
