/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.dom;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.ForStatement;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Initializer;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.VariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;

import org.eclipse.jdt.internal.ui.text.correction.ASTResolving;

/**
 * Evaluates all fields, methods and types available (declared) at a given offset
 * in a compilation unit (Code assist that returns IBindings)
 */
public class ScopeAnalyzer {
	
	private static final IBinding[] NO_BINDING= new IBinding[0];

	/**
	 * Flag to specify that method should be reported.
	 */
	public static final int METHODS= 1;
	
	/**
	 * Flag to specify that variables should be reported.
	 */	
	public static final int VARIABLES= 2;
	
	/**
	 * Flag to specify that types should be reported.
	 */		
	public static final int TYPES= 4;
	
	/**
	 * Flag to specify that only visible elements should be added.
	 */		
	public static final int CHECK_VISIBILITY= 16;
	
	private static interface IBindingRequestor {
		boolean acceptBinding(IBinding binding);
	}
	
	private static class DefaultBindingRequestor implements IBindingRequestor {
		
		private final List fResult;
		private final HashSet fNamesAdded;
		private final int fFlags;
		private final ITypeBinding fParentTypeBinding;
		
		public DefaultBindingRequestor(ITypeBinding parentTypeBinding, int flags) {
			fParentTypeBinding= parentTypeBinding;
			fFlags= flags;
			fResult= new ArrayList();
			fNamesAdded= new HashSet();
		}
		
		public DefaultBindingRequestor() {
			this(null, 0);
		}

		/**
		 * {@inheritDoc}
		 */
		public boolean acceptBinding(IBinding binding) {
			if (binding == null)
				return false;
			
			String signature= getSignature(binding);
			if (signature != null && fNamesAdded.add(signature)) { // avoid duplicated results from inheritance
				fResult.add(binding);
			}
			return false;
		}

		public List getResult() {
			if (hasFlag(CHECK_VISIBILITY, fFlags)) {
				for (int i= fResult.size() - 1; i >= 0; i--) {
					IBinding binding= (IBinding) fResult.get(i);
					if (!isVisible(binding, fParentTypeBinding)) {
						fResult.remove(i);
					}
				}
			}
			return fResult;
		}
		
	}

	private HashSet fTypesVisited;
	
	private CompilationUnit fRoot;
	
	public ScopeAnalyzer(CompilationUnit root) {
		fTypesVisited= new HashSet();
		fRoot= root;
	}
	
	private void clearLists() {
		fTypesVisited.clear();
	}
	
	private static String getSignature(IBinding binding) {
		if (binding != null) {
			switch (binding.getKind()) {
				case IBinding.METHOD:
					StringBuffer buf= new StringBuffer();
					buf.append('M');
					buf.append(binding.getName()).append('(');
					ITypeBinding[] parameters= ((IMethodBinding) binding).getParameterTypes();
					for (int i= 0; i < parameters.length; i++) {
						if (i > 0) {
							buf.append(',');
						}
						ITypeBinding paramType= parameters[i].getErasure();
						buf.append(paramType.getQualifiedName());
					}
					buf.append(')');
					return buf.toString();
				case IBinding.VARIABLE:
					return 'V' + binding.getName();
				case IBinding.TYPE:
					return 'T' + binding.getName();			
			}
		}
		return null;
	}
	
	static final boolean hasFlag(int property, int flags) {
		return (flags & property) != 0;
	}
	
	/**
	 * Collects all elements available in a type and its hierarchy
	 * @param binding The type binding
	 * @param flags Flags defining the elements to report
	 */
	private boolean addInherited(ITypeBinding binding, int flags, IBindingRequestor requestor) {
		if (!fTypesVisited.add(binding)) {
			return false;
		}
		if (hasFlag(VARIABLES, flags)) {
			IVariableBinding[] variableBindings= binding.getDeclaredFields();
			for (int i= 0; i < variableBindings.length; i++) {
				if (requestor.acceptBinding(variableBindings[i]))
					return true;
			}
		}
		
		if (hasFlag(METHODS, flags)) {
			IMethodBinding[] methodBindings= binding.getDeclaredMethods();
			for (int i= 0; i < methodBindings.length; i++) {
				IMethodBinding curr= methodBindings[i];
				if (!curr.isSynthetic() && !curr.isConstructor()) {
					if (requestor.acceptBinding(curr))
						return true;
				}
			}
		}

		if (hasFlag(TYPES, flags)) {
			ITypeBinding[] typeBindings= binding.getDeclaredTypes();
			for (int i= 0; i < typeBindings.length; i++) {
				ITypeBinding curr= typeBindings[i];
				if (requestor.acceptBinding(curr))
					return true;			
			}
		}		
		
		
		ITypeBinding superClass= binding.getSuperclass();
		if (superClass != null) {
			if (addInherited(superClass, flags, requestor)) // recursive
				return true;
		} else if (binding.isArray()) {
			if (addInherited(fRoot.getAST().resolveWellKnownType("java.lang.Object"), flags, requestor)) //$NON-NLS-1$
				return true;
		}
		
		ITypeBinding[] interfaces= binding.getInterfaces(); // includes looking for methods: abstract, unimplemented methods
		for (int i= 0; i < interfaces.length; i++) {
			if (addInherited(interfaces[i], flags, requestor)) // recursive
				return true;
		}
		return false;
	}
		
	
	/**
	 * Collects all elements available in a type: its hierarchy and its outer scopes.
	 * @param binding The type binding
	 * @param flags Flags defining the elements to report
	 */
	private boolean addTypeDeclarations(ITypeBinding binding, int flags, IBindingRequestor requestor) {
		if (hasFlag(TYPES, flags) && !binding.isAnonymous()) {
			if (requestor.acceptBinding(binding))
				return true;
			
			ITypeBinding[] typeParameters= binding.getTypeParameters();
			for (int i= 0; i < typeParameters.length; i++) {
				if (requestor.acceptBinding(typeParameters[i]))
					return true;
			}
		}
		
		addInherited(binding, flags, requestor); // add inherited 
		
		if (binding.isLocal()) {
			addOuterDeclarationsForLocalType(binding, flags, requestor);
		} else {
			ITypeBinding declaringClass= binding.getDeclaringClass();
			if (declaringClass != null) {
				if (addTypeDeclarations(declaringClass, flags, requestor)) // Recursively add inherited
					return true;
			} else if (hasFlag(TYPES, flags)) {
				if (fRoot.findDeclaringNode(binding) != null) {
					List types= fRoot.types();
					for (int i= 0; i < types.size(); i++) {
						if (requestor.acceptBinding(((AbstractTypeDeclaration) types.get(i)).resolveBinding()))
							return true;
					}
				}
			}
		}
		return false;
	}
	
	private boolean addOuterDeclarationsForLocalType(ITypeBinding localBinding, int flags, IBindingRequestor requestor) {
		ASTNode node= fRoot.findDeclaringNode(localBinding);
		if (node == null) {
			return false;
		}
		
		if (node instanceof AbstractTypeDeclaration || node instanceof AnonymousClassDeclaration) {
			if (addLocalDeclarations(node.getParent(), flags, requestor))
				return true;
			
			ITypeBinding parentTypeBinding= Bindings.getBindingOfParentType(node.getParent());
			if (parentTypeBinding != null) {
				if (addTypeDeclarations(parentTypeBinding, flags, requestor))
					return true;
			}
			
		}
		return false;
	}
	
	private static ITypeBinding getBinding(Expression node) {
		if (node != null) {
			return node.resolveTypeBinding();
		}
		return null;
	}
		
	private static ITypeBinding getQualifier(SimpleName selector) {
		ASTNode parent= selector.getParent();
		switch (parent.getNodeType()) {
			case ASTNode.METHOD_INVOCATION:
				MethodInvocation decl= (MethodInvocation) parent;
				if (selector == decl.getName()) {
					return getBinding(decl.getExpression());
				}
				return null;
			case ASTNode.QUALIFIED_NAME:
				QualifiedName qualifiedName= (QualifiedName) parent;
				if (selector == qualifiedName.getName()) {
					return getBinding(qualifiedName.getQualifier());
				}
				return null;
			case ASTNode.FIELD_ACCESS:
				FieldAccess fieldAccess= (FieldAccess) parent;
				if (selector == fieldAccess.getName()) {
					return getBinding(fieldAccess.getExpression());
				}
				return null;			
			case ASTNode.SUPER_FIELD_ACCESS: {
				ITypeBinding curr= Bindings.getBindingOfParentType(parent);
				return curr.getSuperclass();
			}
			case ASTNode.SUPER_METHOD_INVOCATION: {
				SuperMethodInvocation superInv= (SuperMethodInvocation) parent;
				if (selector == superInv.getName()) {
					ITypeBinding curr= Bindings.getBindingOfParentType(parent);
					return curr.getSuperclass();
				}
				return null;
			}
			default:
				if (parent instanceof Type) {
					// bug 67644: in 'a.new X()', all member types of A are visible as location of X. 
					ASTNode normalizedNode= ASTNodes.getNormalizedNode(parent);
					if (normalizedNode.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY) {
						ClassInstanceCreation creation= (ClassInstanceCreation) normalizedNode.getParent();
						return getBinding(creation.getExpression());
					}
				}
				return null;
		}
	}
	
	public IBinding[] getDeclarationsInScope(SimpleName selector, int flags) {
		try {
			// special case for switch on enum
			if (selector.getLocationInParent() == SwitchCase.EXPRESSION_PROPERTY) {
				ITypeBinding binding= ((SwitchStatement) selector.getParent().getParent()).getExpression().resolveTypeBinding();
				if (binding != null && binding.isEnum()) {
					return getEnumContants(binding);
				}
			}
			
			ITypeBinding parentTypeBinding= Bindings.getBindingOfParentType(selector);
			if (parentTypeBinding != null) {			
				ITypeBinding binding= getQualifier(selector);
				DefaultBindingRequestor requestor= new DefaultBindingRequestor(parentTypeBinding, flags);
				if (binding == null) {
					addLocalDeclarations(selector, flags, requestor);
					addTypeDeclarations(parentTypeBinding, flags, requestor);
				} else {
					addInherited(binding, flags, requestor);
				}

				List result= requestor.getResult();
				return (IBinding[]) result.toArray(new IBinding[result.size()]);
			}
			return NO_BINDING;
		} finally {
			clearLists();			
		}
	}
	
	private static class SearchRequestor implements IBindingRequestor {
		
		private final int fFlags;
		private final ITypeBinding fParentTypeBinding;
		private final IBinding fToSearch;
		private boolean fFound;
		private boolean fIsVisible;
		
		public SearchRequestor(IBinding toSearch, ITypeBinding parentTypeBinding, int flag) {
			fFlags= flag;
			fToSearch= toSearch;
			fParentTypeBinding= parentTypeBinding;
			fFound= false;
			fIsVisible= true;
		}
		
		public boolean acceptBinding(IBinding binding) {
			if (fFound)
				return true;
			
			if (binding == null)
				return false;
			
			if (fToSearch.getKind() != binding.getKind()) {
				return false;
			}
			
			
			if (binding == fToSearch) {
				fFound= true;
			} else {
				binding= Bindings.getDeclaration(binding);
				if (binding == fToSearch) {
					fFound= true;
				} else if (binding.getName().equals(fToSearch.getName())) {
					String signature= getSignature(binding);
					if (signature != null && signature.equals(getSignature(fToSearch))) {
						fIsVisible= false;
						return true; // found element that hides the binding to find
					}
				}
			}
			if (fFound && hasFlag(CHECK_VISIBILITY, fFlags)) {
				fIsVisible= ScopeAnalyzer.isVisible(binding, fParentTypeBinding);
			}
			return fFound;
		}
		
		public boolean found() {
			return fFound;
		}

		public boolean isVisible() {
			return fIsVisible;
		}
	}
	
	public boolean isDeclaredInScope(IBinding declaration, SimpleName selector, int flags) {
		try {
			// special case for switch on enum
			if (selector.getLocationInParent() == SwitchCase.EXPRESSION_PROPERTY) {
				ITypeBinding binding= ((SwitchStatement) selector.getParent().getParent()).getExpression().resolveTypeBinding();
				if (binding != null && binding.isEnum()) {
					return hasEnumContants(declaration, binding);
				}
			}
			
			ITypeBinding parentTypeBinding= Bindings.getBindingOfParentType(selector);
			if (parentTypeBinding != null) {			
				ITypeBinding binding= getQualifier(selector);
				SearchRequestor requestor= new SearchRequestor(declaration, parentTypeBinding, flags);
				if (binding == null) {
					addLocalDeclarations(selector, flags, requestor);
					if (requestor.found())
						return requestor.isVisible();
					addTypeDeclarations(parentTypeBinding, flags, requestor);
					if (requestor.found())
						return requestor.isVisible();
				} else {
					addInherited(binding, flags, requestor);
					if (requestor.found())
						return requestor.isVisible();
				}
			}
			return false;
		} finally {
			clearLists();
		}
	}
	
	private IVariableBinding[] getEnumContants(ITypeBinding binding) {
		IVariableBinding[] declaredFields= binding.getDeclaredFields();
		ArrayList res= new ArrayList(declaredFields.length);
		for (int i= 0; i < declaredFields.length; i++) {
			IVariableBinding curr= declaredFields[i];
			if (curr.isEnumConstant()) {
				res.add(curr);
			}
		}
		return (IVariableBinding[]) res.toArray(new IVariableBinding[res.size()]);
	}
	
	private boolean hasEnumContants(IBinding declaration, ITypeBinding binding) {
		IVariableBinding[] declaredFields= binding.getDeclaredFields();
		for (int i= 0; i < declaredFields.length; i++) {
			IVariableBinding curr= declaredFields[i];
			if (curr == declaration)
				return true;
		}
		return false;
	}

	public IBinding[] getDeclarationsInScope(int offset, int flags) {
		NodeFinder finder= new NodeFinder(offset, 0);
		fRoot.accept(finder);
		ASTNode node= finder.getCoveringNode();
		if (node == null) {
			return NO_BINDING;
		}

		if (node instanceof SimpleName) {
			return getDeclarationsInScope((SimpleName) node, flags);
		}
		
		try {
			ITypeBinding binding= Bindings.getBindingOfParentType(node);
			DefaultBindingRequestor requestor= new DefaultBindingRequestor(binding, flags);
			addLocalDeclarations(node, offset, flags, requestor);			
			if (binding != null) {
				addTypeDeclarations(binding, flags, requestor);
			}
			List result= requestor.getResult();
			return (IBinding[]) result.toArray(new IBinding[result.size()]);
		} finally {
			clearLists();			
		}
	}
	
	private static ITypeBinding getDeclaringType(IBinding binding) {
		switch (binding.getKind()) {
			case IBinding.VARIABLE:
				return ((IVariableBinding) binding).getDeclaringClass();
			case IBinding.METHOD:
				return ((IMethodBinding) binding).getDeclaringClass();
			case IBinding.TYPE:
				ITypeBinding typeBinding= (ITypeBinding) binding;
				if (typeBinding.getDeclaringClass() != null) {
					return typeBinding;
				}
				return typeBinding;
		}
		return null;
	}
	
	/**
	 * Evaluates if the declaration is visible in a certain context. 
	 * @param binding The binding of the declaration to examine
	 * @param context The context to test in
	 * @return Returns 
	 */
	public static boolean isVisible(IBinding binding, ITypeBinding context) {
		if (binding.getKind() == IBinding.VARIABLE && !((IVariableBinding) binding).isField()) {
			return true; // all local variables found are visible
		}
		ITypeBinding declaring= getDeclaringType(binding);
		if (declaring == null) {
			return false;
		}
	
		int modifiers= binding.getModifiers();
		if (Modifier.isPublic(modifiers) || declaring.isInterface()) {
			return true;
		} else if (Modifier.isProtected(modifiers) || !Modifier.isPrivate(modifiers)) {
			if (declaring.getPackage() == context.getPackage()) {
				return true;
			}
			return isTypeInScope(declaring, context, Modifier.isProtected(modifiers));
		}
		// private visibility
		return isTypeInScope(declaring, context, false);
	}
	
	private static boolean isTypeInScope(ITypeBinding declaring, ITypeBinding context, boolean includeHierarchy) {
		ITypeBinding curr= context;
		while (curr != null && curr != declaring) {
			if (includeHierarchy && Bindings.isSuperType(declaring, curr)) {
				return true;
			}
			curr= curr.getDeclaringClass();
		}
		return curr == declaring;
	}
	

	public IBinding[] getDeclarationsAfter(int offset, int flags) {
		try {		
			NodeFinder finder= new NodeFinder(offset, 0);
			fRoot.accept(finder);
			ASTNode node= finder.getCoveringNode();
			if (node == null) {
				return null;
			}
			
			ASTNode declaration= ASTResolving.findParentStatement(node);
			while (declaration instanceof Statement && declaration.getNodeType() != ASTNode.BLOCK) {
				declaration= declaration.getParent();
			}

			if (declaration instanceof Block) {
				DefaultBindingRequestor requestor= new DefaultBindingRequestor();
				DeclarationsAfterVisitor visitor= new DeclarationsAfterVisitor(node.getStartPosition(), flags, requestor);
				declaration.accept(visitor);
				List result= requestor.getResult();
				return (IBinding[])result.toArray(new IBinding[result.size()]);
			}
			return NO_BINDING;
		} finally {
			clearLists();			
		}
	}
	
	
	private class ScopeAnalyzerVisitor extends HierarchicalASTVisitor {
		
		private int fPosition;
		private int fFlags;
		private final IBindingRequestor fRequestor;
		private boolean fBreak;
		
		public ScopeAnalyzerVisitor(int position, int flags, IBindingRequestor requestor) {
			fPosition= position;
			fFlags= flags;
			fRequestor= requestor;
			fBreak= false;
		}
		
		private boolean isInside(ASTNode node) {
			int start= node.getStartPosition();
			int end= start + node.getLength();
					
			return start <= fPosition && fPosition < end;
		}
		
		public boolean visit(MethodDeclaration node) {
			if (isInside(node)) {
				Block body= node.getBody();
				if (body != null) {
					body.accept(this);
				}
				visitBackwards(node.parameters());
				if (node.getAST().apiLevel() >= AST.JLS3) {
					visitBackwards(node.typeParameters());
				}
			}
			return false;
		}
		
		
		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.TypeParameter)
		 */
		public boolean visit(TypeParameter node) {
			if (hasFlag(TYPES, fFlags) && node.getStartPosition() < fPosition) {
				fBreak= fRequestor.acceptBinding(node.getName().resolveBinding());
			}
			return !fBreak;
		}
				
		public boolean visit(SwitchCase node) {
			// switch on enum allows to use enum constants without qualification
			if (hasFlag(VARIABLES, fFlags) && !node.isDefault() && isInside(node.getExpression())) {
				SwitchStatement switchStatement= (SwitchStatement) node.getParent();
				ITypeBinding binding= switchStatement.getExpression().resolveTypeBinding();
				if (binding != null && binding.isEnum()) {
					IVariableBinding[] declaredFields= binding.getDeclaredFields();
					for (int i= 0; i < declaredFields.length; i++) {
						IVariableBinding curr= declaredFields[i];
						if (curr.isEnumConstant()) {
							fBreak= fRequestor.acceptBinding(curr);
							if (fBreak)
								return false;
						}
					}
				}
			}
			return false;
		}
		
		public boolean visit(Initializer node) {
			return !fBreak && isInside(node);
		}		
		
		public boolean visit(Statement node) {
			return !fBreak && isInside(node);
		}
		
		public boolean visit(ASTNode node) {
			return false;
		}
		
		public boolean visit(Block node) {
			if (isInside(node)) {
				visitBackwards(node.statements());
			}
			return false;
		}		
		
		public boolean visit(VariableDeclaration node) {
			if (hasFlag(VARIABLES, fFlags) && node.getStartPosition() < fPosition) {
				fBreak= fRequestor.acceptBinding(node.resolveBinding());					
			}
			return !fBreak;
		}
		
		public boolean visit(VariableDeclarationStatement node) {
			visitBackwards(node.fragments());
			return false;
		}		
		
		public boolean visit(VariableDeclarationExpression node) {
			visitBackwards(node.fragments());
			return false;
		}
	
		public boolean visit(CatchClause node) {
			if (isInside(node)) {
				node.getBody().accept(this);
				node.getException().accept(this);
			}
			return false;			
		}
		
		public boolean visit(ForStatement node) {
			if (isInside(node)) {
				node.getBody().accept(this);
				visitBackwards(node.initializers());
			}
			return false;
		}	
	
		public boolean visit(TypeDeclarationStatement node) {
			if (hasFlag(TYPES, fFlags) && node.getStartPosition() + node.getLength() < fPosition) {
				if (node.getAST().apiLevel() == AST.JLS2) {
					fBreak= fRequestor.acceptBinding(node.getTypeDeclaration().resolveBinding());
				} else {
					fBreak= fRequestor.acceptBinding(node.getDeclaration().getName().resolveBinding());
				}
				return false;
			}
			return !fBreak && isInside(node);
		}
		
		private void visitBackwards(List list) {
			if (fBreak)
				return;
			
			for (int i= list.size() - 1; i >= 0; i--) {
				ASTNode curr= (ASTNode) list.get(i);
				if (curr.getStartPosition() <  fPosition) {
					curr.accept(this);
				}
			}			
		}
	}
	
	private class DeclarationsAfterVisitor extends HierarchicalASTVisitor {
		private final int fPosition;
		private final int fFlags;
		private final IBindingRequestor fRequestor;
		private boolean fBreak;
		
		public DeclarationsAfterVisitor(int position, int flags, IBindingRequestor requestor) {
			fPosition= position;
			fFlags= flags;
			fRequestor= requestor;
			fBreak= false;
		}
		
		public boolean visit(ASTNode node) {
			return !fBreak;
		}
		
		public boolean visit(VariableDeclaration node) {
			if (hasFlag(VARIABLES, fFlags) && fPosition < node.getStartPosition()) {
				fBreak= fRequestor.acceptBinding(node.resolveBinding());		
			}
			return false;
		}
		
		public boolean visit(AnonymousClassDeclaration node) {
			return false;
		}

		public boolean visit(TypeDeclarationStatement node) {
			if (hasFlag(TYPES, fFlags) && fPosition < node.getStartPosition()) {
				if (node.getAST().apiLevel() == AST.JLS2) {
					fBreak= fRequestor.acceptBinding(node.getTypeDeclaration().resolveBinding());
				} else {
					fBreak= fRequestor.acceptBinding(node.getDeclaration().getName().resolveBinding());
				}
			}
			return false;
		}
	}
	
	private boolean addLocalDeclarations(ASTNode node, int flags, IBindingRequestor requestor) {
		return addLocalDeclarations(node, node.getStartPosition(), flags, requestor);
	}
	
	
	private boolean addLocalDeclarations(ASTNode node, int offset, int flags, IBindingRequestor requestor) {
		if (hasFlag(VARIABLES, flags) || hasFlag(TYPES, flags)) {
			BodyDeclaration declaration= ASTResolving.findParentBodyDeclaration(node);
			if (declaration instanceof MethodDeclaration || declaration instanceof Initializer) {		
				ScopeAnalyzerVisitor visitor= new ScopeAnalyzerVisitor(offset, flags, requestor);
				declaration.accept(visitor);
				return visitor.fBreak;
			}
		}
		return false;
	}
	
}
