Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=149221

Refactored design time bean introspection into its own set of libs in jsf.core.  Implicit bean property rules including boolean is accessor are now more correctly implemented and called from the java type descriptor
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/META-INF/MANIFEST.MF b/jsf/plugins/org.eclipse.jst.jsf.core/META-INF/MANIFEST.MF
index 91302a1..6caff12 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/META-INF/MANIFEST.MF
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/META-INF/MANIFEST.MF
@@ -37,4 +37,5 @@
  org.eclipse.jst.jsf.core.internal.project.facet;x-friends:="org.eclipse.jst.jsf.core.tests,org.eclipse.jst.jsf.ui,org.eclipse.jst.jsf.ui.tests",
  org.eclipse.jst.jsf.core.internal.provisional.jsfappconfig,
  org.eclipse.jst.jsf.core.internal.provisional.jsflibraryregistry,
- org.eclipse.jst.jsf.core.internal.types
+ org.eclipse.jst.jsf.core.internal.types,
+ org.eclipse.jst.jsf.core.internal.provisional.util
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/JDTBeanIntrospector.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/JDTBeanIntrospector.java
new file mode 100644
index 0000000..e2d77a6
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/JDTBeanIntrospector.java
@@ -0,0 +1,196 @@
+package org.eclipse.jst.jsf.core.internal.provisional.util;
+
+import java.beans.Introspector;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
+
+/**
+ * A class that does bean introspector on a JDT IType
+ * 
+ * @author cbateman
+ *
+ */
+public class JDTBeanIntrospector 
+{
+	private final static String GET_PREFIX = "get";
+	private final static String SET_PREFIX = "set";
+	private final static String IS_PREFIX = "is";
+	
+	private final IType 	_type;
+
+	/**
+	 * @param type
+	 */
+	public JDTBeanIntrospector(IType type)
+	{
+		_type = type;
+	}
+	
+	/**
+	 * @return an map of all properties with the property names
+     * as keys and the values being JDTBeanProperty objects representing
+     * the properties.
+	 */
+	public Map getProperties()
+	{
+		final Map	    propertiesWorkingCopy = new HashMap();
+		final IMethod[] methods = getAllMethods();
+		
+		for (int i = 0; i < methods.length; i++)
+		{
+			final IMethod  method = methods[i];
+
+			try
+			{
+				processPropertyMethod(method, propertiesWorkingCopy);
+			}
+			catch (JavaModelException jme)
+			{
+				// log and then proceed to next method
+				JSFCorePlugin.log(jme, "Error processing IMethod for bean property info");
+			}
+		}
+		
+        final Map properties = new HashMap();
+        
+        for (final Iterator it = propertiesWorkingCopy.keySet().iterator(); it.hasNext();)
+        {
+            final String key = (String) it.next();
+            JDTBeanPropertyWorkingCopy  wcopy = 
+                (JDTBeanPropertyWorkingCopy) propertiesWorkingCopy.get(key);
+            properties.put(key, wcopy.toValueObject());
+        }
+        
+		return properties;
+	}
+	
+	private void processPropertyMethod(IMethod method, Map properties) throws JavaModelException
+	{
+		// to be a bean method, it must not a constructor, must be public
+		// and must not be static
+		if (!method.isConstructor()
+				&& (method.getFlags() & Flags.AccPublic) != 0
+				&& (method.getFlags() & Flags.AccStatic) == 0)
+		{
+			final String methodName = method.getElementName();
+			final String returnType = method.getReturnType();
+			
+			// either starts with get or is boolean and starts with is
+			
+			// is access must start with 'is', have a boolean return type and no parameters
+			final boolean  startsWithIs = methodName.startsWith(IS_PREFIX) 
+					&& Signature.SIG_BOOLEAN.equals(returnType)
+					&& method.getNumberOfParameters() == 0
+                    && methodName.length() > IS_PREFIX.length();
+			
+			// get accessor must start with 'get', have no parameters and return non-void
+			final boolean  startsWithGet = (methodName.startsWith(GET_PREFIX)
+											&& method.getNumberOfParameters() == 0)
+											&& !Signature.SIG_VOID.equals(returnType)                    
+                                            && methodName.length() > GET_PREFIX.length();
+			
+			// mutator must start with 'set' and have one parameter and a void return type
+			final boolean  startsWithSet = methodName.startsWith(SET_PREFIX)
+											&& method.getNumberOfParameters() == 1
+											&& Signature.SIG_VOID.equals(returnType)
+                                            && methodName.length() > SET_PREFIX.length();
+
+			if (startsWithGet || startsWithSet || startsWithIs)
+			{
+				final String propertyName = 
+					Introspector.decapitalize(methodName.substring(startsWithIs ? 2 : 3));
+
+				JDTBeanPropertyWorkingCopy workingCopy = 
+					(JDTBeanPropertyWorkingCopy) properties.get(propertyName);
+				
+				if (workingCopy == null)
+				{
+					workingCopy = new JDTBeanPropertyWorkingCopy(_type);
+					properties.put(propertyName, workingCopy);
+				}
+				
+				if  (startsWithIs)
+				{
+					workingCopy.setIsGetter(method);
+				}
+				else if (startsWithGet)
+				{
+					workingCopy.setGetter(method);
+				}
+				else if (startsWithSet)
+				{
+					workingCopy.addSetter(method);
+				}
+			}
+		}
+	}
+	
+	
+	/**
+	 * @return all methods for the type including inherited ones
+	 */
+	public IMethod[] getAllMethods()
+	{
+		IMethod[] methods = new IMethod[0];
+		
+		try
+		{
+            // type not resolved so don't proceed
+            if (_type != null)
+            {
+	            // TODO: type hierarchy is potentially expensive, should
+	            // cache once and listen for changes
+	            ITypeHierarchy  hierarchy = _type.newSupertypeHierarchy(new NullProgressMonitor());
+	            
+				methods = getAllMethods(hierarchy, _type);
+            }
+		}
+		catch(JavaModelException jme)
+		{
+			JSFCorePlugin.log(jme, "Error getting type information for bean");
+		}
+
+		return methods;
+	}
+	
+    /**
+     * @param typeHierarchy
+     * @param type
+     * @return all methods of the type and it's super types
+     */
+    private static IMethod[] getAllMethods(final ITypeHierarchy typeHierarchy, final IType type)
+    {
+        final List   methods = new ArrayList();
+        final IType[] superTypes = typeHierarchy.getAllSuperclasses(type);
+        final IType[] closure = new IType[superTypes.length+1];
+        closure[0] = type;
+        System.arraycopy(superTypes, 0, closure, 1, superTypes.length);
+        
+        for (int i = 0; i < superTypes.length; i++)
+        {
+            try {
+                final IType superType = closure[i];
+                methods.addAll(Arrays.asList(superType.getMethods()));
+            } catch (JavaModelException e) {
+    			JSFCorePlugin.log(e, "Error getting super type information for bean");
+            }
+        }
+            
+        return (IMethod[]) methods.toArray(new IMethod[0]);
+    }
+
+	
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/JDTBeanProperty.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/JDTBeanProperty.java
new file mode 100644
index 0000000..f71953e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/JDTBeanProperty.java
@@ -0,0 +1,136 @@
+package org.eclipse.jst.jsf.core.internal.provisional.util;
+
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
+
+/**
+ * Represents a single bean property backed by JDT data
+ * 
+ * @author cbateman
+ *
+ */
+public class JDTBeanProperty 
+{
+	/**
+	 * the IMethod for the accessor  (either is or get)
+	 */
+	private IMethod   _getter;
+	
+	/**
+	 * the IMethod for a "set" accessor method
+	 */
+	private IMethod   _setter;
+
+	/**
+	 * The IType that this property belongs to
+	 */
+	protected final IType    _type;
+    
+    /**
+     * @param type
+     */
+    protected JDTBeanProperty(IType type)
+    {
+        _type = type;
+    }
+
+    /**
+	 * @return true if this property is readable
+	 */
+	public boolean isReadable()
+	{
+		return  _getter != null;
+	}
+	
+	/**
+	 * @return true if this property is writable
+	 */
+	public boolean isWritable()
+	{
+		return _setter != null;
+	}
+	
+	
+	/**
+	 * @return the get accessor IMethod or null if none
+	 */
+	public IMethod getGetter() {
+		return _getter;
+	}
+
+	
+	
+	/**
+	 * Set the get accessor IMethod
+	 * @param getter -- maybe null to indicate none
+	 */
+	void setGetter(IMethod getter) {
+		_getter = getter;
+	}
+
+
+	/**
+	 * @return the set mutator IMethod or null if none
+	 */
+	public IMethod getSetter() {
+		return _setter;
+	}
+
+	/**
+	 * @param setter
+	 */
+	void setSetter(IMethod setter) {
+		_setter = setter;
+	}
+	
+    /**
+     * @return the IType for this property's type or null if it
+     * cannot determined.  Note that null does not necessarily indicate an error
+     * since some types like arrays of things do not have corresponding JDT IType's
+     */
+    public IType getType()
+    {
+        final String typeSignature = getTypeSignature();
+        return TypeUtil.resolveType(_type, typeSignature);
+    }
+	
+	/**
+	 * @return the fully resolved (if possible) type signature for
+     * the property or null if unable to determine
+	 */
+	public String getTypeSignature()
+    {
+        try
+        {
+            String unResolvedSig = getUnresolvedType();
+            final String signature = TypeUtil.resolveTypeSignature(_type, unResolvedSig);
+            return signature;
+        }
+        catch (JavaModelException jme)
+        {
+            JSFCorePlugin.log(jme, "Error resolving bean property type signature");
+            return null;
+        }
+    }
+
+    private String getUnresolvedType() throws JavaModelException
+    {
+        String   typeSig = null;
+        
+        // first decide which method to use; getter always gets precendence
+        if (_getter != null)
+        {
+            typeSig = _getter.getReturnType();
+        }
+        // TODO: if no getter or setter could we have been created?
+        // use setter
+        else
+        {
+            typeSig = _setter.getParameterTypes()[0];
+        }
+        
+        return typeSig;
+    }
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/JDTBeanPropertyWorkingCopy.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/JDTBeanPropertyWorkingCopy.java
new file mode 100644
index 0000000..d2c8926
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/JDTBeanPropertyWorkingCopy.java
@@ -0,0 +1,151 @@
+package org.eclipse.jst.jsf.core.internal.provisional.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
+
+/**
+ * A writable version of the JDTBeanProperty object
+ * 
+ * @author cbateman
+ *
+ */
+public class JDTBeanPropertyWorkingCopy extends JDTBeanProperty 
+{
+	private final List		_setters;
+	
+	/**
+	 * the IMethod for the boolean "is" accessor method
+	 */
+	private IMethod        _isGetter;
+	
+	/**
+	 * Constructor
+	 * @param type 
+	 */
+	public JDTBeanPropertyWorkingCopy(IType type)
+	{
+        super(type);
+		_setters = new ArrayList();
+	}
+	
+	/**
+	 * @return the bean properties spawned from this working copy
+	 * Normally, there is only one property in the array, however,
+	 * since this working copy represents all properties with the same
+	 * name, there could be multiple properties since setters can
+	 * be overloaded by name and could result in zero or one readable
+	 * properties plus zero or more write-only properties with the same
+	 * name.  I can't see anywhere in the spec that covers this 
+	 * boundary case
+	 */
+	public JDTBeanProperty toValueObject()
+	{
+		// if the isGetter is present that it takes precedence
+		// over the the normal getter
+		IMethod  getter = getIsGetter() != null ? 
+							getIsGetter() : getGetter();
+		IMethod  matchedSetter = null;
+
+		if (getter != null)
+		{
+			matchedSetter = determineMatchedSetter(getter);
+		}
+		// if there's no getter than pick any setter: there
+		// are bigger problem when there's no getter than
+		// ambiguous setters
+		else if (_setters.size() > 0)
+		{
+			matchedSetter = (IMethod) _setters.get(0);
+		}
+		
+		JDTBeanProperty beanProp = new JDTBeanProperty(_type);
+		beanProp.setGetter(getter);
+		beanProp.setSetter(matchedSetter);
+		return beanProp;
+	}
+	
+	private IMethod determineMatchedSetter(IMethod getter)
+	{
+		IMethod matchedSetter = null;
+		
+		try
+		{
+			final String getterSig = 
+				TypeUtil.resolveTypeSignature(_type, getter.getReturnType());
+
+			FIND_MATCHING_SETTER:for 
+				(final Iterator it = _setters.iterator(); it.hasNext();)
+			{
+				final IMethod  setter = (IMethod) it.next();
+				if (setter.getNumberOfParameters() == 1)
+				{
+					final String paramSig = 
+						TypeUtil.resolveTypeSignature
+							(_type,setter.getParameterTypes()[0]);
+					
+					if (paramSig.equals(getterSig))
+					{
+						// we've found our match since only one
+						// setter with the same name as the getter
+						// can have the same matching type for a
+						// single arg method
+						matchedSetter = setter;
+						break FIND_MATCHING_SETTER;
+					}
+				}
+			}
+		}
+		catch (JavaModelException jme)
+		{
+			JSFCorePlugin.log(jme, "Error determining getter return type, bean properties analysis may be inaccurate");
+		}
+
+		return matchedSetter;
+	}
+	
+	//@Override
+	public void setGetter(IMethod getter) {
+		super.setGetter(getter);
+	}
+
+	/**
+	 * @param isGetter
+	 */
+	public void setIsGetter(IMethod isGetter) {
+		_isGetter = isGetter;
+	}
+
+	/**
+	 * @param setter
+	 */
+	public void addSetter(IMethod setter) {
+        if (setter != null
+                && setter.getNumberOfParameters() == 1)
+        {
+            _setters.add(setter);
+        }
+	}
+
+    /**
+     * Not supported on working copy.  This is synthetically generated
+     * on toValueObject()
+     * @return nothing; throws exception
+     */
+    public final IMethod getSetter()
+    {
+        throw new UnsupportedOperationException("Setter not calculated in working copy.  Call toValueObject().getSetter()");
+    }
+    
+	/**
+	 * @return the "is" getter method or null if not found
+	 */
+	public IMethod getIsGetter() {
+		return _isGetter;
+	}
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/TypeUtil.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/TypeUtil.java
new file mode 100644
index 0000000..9af926b
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/provisional/util/TypeUtil.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Oracle Corporation.
+ * 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:
+ *    Cameron Bateman/Oracle - initial API and implementation
+ *    
+ ********************************************************************************/
+
+package org.eclipse.jst.jsf.core.internal.provisional.util;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
+
+/**
+ * Utility for handling IType's and type signatures
+ * 
+ * @author cbateman
+ *
+ */
+public final class TypeUtil 
+{
+    static IType resolveType(final IType owningType, final String typeSignature)
+    {
+        // if type signature is already resolved then simply look it up
+        if (typeSignature.charAt(0) == Signature.C_RESOLVED
+        		|| (Signature.getTypeSignatureKind(typeSignature) == Signature.ARRAY_TYPE_SIGNATURE
+        			&& Signature.getElementType(typeSignature).charAt(0) == Signature.C_RESOLVED))
+        {
+            IType type = null;
+            
+            try
+            {
+                type = owningType.getJavaProject().
+                           findType(getFullyQualifiedName(typeSignature));
+            }
+            catch (JavaModelException jme)
+            {
+                // do nothing; return type == null;
+            }
+            
+            return type;
+        }
+        
+        
+        return resolveTypeRelative(owningType, typeSignature);
+    }
+
+    
+    /**
+     * @param owningType
+     * @param typeSignature
+     * @return the resolved type signature for typeSignature in owningType
+     */
+    public static String resolveTypeSignature(final IType owningType, final String typeSignature)
+    {
+        final int sigKind = Signature.getTypeSignatureKind(typeSignature);
+    
+        switch (sigKind)
+        {
+            case Signature.BASE_TYPE_SIGNATURE:
+                return typeSignature;
+                
+            case Signature.ARRAY_TYPE_SIGNATURE:
+            {
+                final String elementType = Signature.getElementType(typeSignature);
+                
+                if (Signature.getTypeSignatureKind(elementType) == Signature.BASE_TYPE_SIGNATURE)
+                {
+                    return typeSignature;
+                }
+
+                final String resolvedElementType = resolveSignatureRelative(owningType, elementType);
+                String resultType = "";
+                for (int i = 0; i < Signature.getArrayCount(typeSignature);i++)
+                {
+                    resultType+=Signature.C_ARRAY;
+                }
+                
+                return resultType+resolvedElementType;
+            }
+            
+            case Signature.CLASS_TYPE_SIGNATURE:
+                return resolveSignatureRelative(owningType, typeSignature);
+    
+            default:
+                return typeSignature;
+        }
+    }
+    
+    /**
+     * @param owningType -- type relative to which typeSignature will be resolved
+     * @param typeSignature -- non-array type signature
+     * @return the resolved type signature if possible or typeSignature if not
+     */
+    private static String resolveSignatureRelative(final IType owningType, final String typeSignature)
+    {
+        String  adjustedTypeSignature = typeSignature;
+       
+        // if already fully resolved, return the input
+        if (adjustedTypeSignature.charAt(0) == Signature.C_RESOLVED)
+        {
+            return typeSignature;
+        }
+
+        IType resolvedType = resolveTypeRelative(owningType, adjustedTypeSignature);
+
+        if (resolvedType != null)
+        {
+            String  resolvedTypeSignature = 
+                Signature.createTypeSignature
+                    (resolvedType.getFullyQualifiedName(), true);
+           
+            return resolvedTypeSignature;
+        }
+
+        if (Signature.getTypeSignatureKind(typeSignature) == 
+                Signature.CLASS_TYPE_SIGNATURE)
+        {
+            // TODO: is there a better way to handle a failure to resolve
+            // than just garbage out?
+            JSFCorePlugin.log(new Exception("Failed to resolve type: "+typeSignature), "Failed to resolve type: "+typeSignature);
+        }
+        
+        return typeSignature;
+    }
+
+    private static IType resolveTypeRelative(final IType owningType, final String typeSignature)
+    {
+        final String fullName = getFullyQualifiedName(typeSignature);
+        
+        IType resolvedType = null;
+        
+        try
+        {
+            String[][] resolved = owningType.resolveType(fullName);
+    
+            if (resolved != null && resolved.length > 0)
+            {
+                resolvedType = owningType.getJavaProject().findType(resolved[0][0], resolved[0][1]);
+            }
+            else
+            {
+                resolvedType = resolveInParents(owningType, fullName);
+            }
+        }
+        catch (JavaModelException jme)
+        {
+            //  do nothing; newType == null
+        }
+
+        return resolvedType;
+    }
+
+    /**
+     * @param type
+     * @return a type signature for a type
+     */
+    public static String getSignature(IType type)
+    {
+        final String fullyQualifiedName = type.getFullyQualifiedName();
+        return Signature.createTypeSignature(fullyQualifiedName, true);
+    }
+
+    
+    /**
+     * @param owner
+     * @param unresolvedSignature
+     * @return the resolved method signature for unresolvedSignature in owner
+     */
+    public static String resolveMethodSignature(final IType  owner, 
+                                         final String unresolvedSignature)
+    {
+        // get the list of parameters
+        final String[] parameters = 
+            Signature.getParameterTypes(unresolvedSignature);
+        
+        for (int i = 0; i < parameters.length; i++)
+        {
+            // try to full resolve the type
+            parameters[i] = resolveTypeSignature(owner, parameters[i]);
+        }
+        
+        // resolve return type
+        final String resolvedReturn = 
+            resolveTypeSignature(owner, 
+                                  Signature.getReturnType(unresolvedSignature));
+        
+        return Signature.createMethodSignature(parameters, resolvedReturn);
+    }
+    
+    private static String getFullyQualifiedName(final String typeSignature)
+    {
+        final String packageName = Signature.getSignatureQualifier(typeSignature);
+        final String typeName = Signature.getSignatureSimpleName(typeSignature);
+        return "".equals(packageName) ? typeName : packageName + "." + typeName;
+    }
+    
+    private static IType resolveInParents(IType  childType, String fullyQualifiedName)
+                                throws JavaModelException
+    {
+        IType resolvedType = null;
+        
+        // not resolved? try the supertypes
+        final ITypeHierarchy typeHierarchy =
+            childType.newSupertypeHierarchy(new NullProgressMonitor());
+        IType[] superTypes = typeHierarchy.getAllSupertypes(childType);
+        String[][]   resolved;
+        
+        LOOP_UNTIL_FIRST_MATCH:
+            for (int i = 0; i < superTypes.length; i++)
+        {
+            IType type = superTypes[i];
+            resolved = type.resolveType(fullyQualifiedName);
+            
+            if (resolved != null && resolved.length > 0)
+            {
+                resolvedType = childType.getJavaProject().findType(resolved[0][0], resolved[0][1]);
+                break LOOP_UNTIL_FIRST_MATCH;
+            }
+        }
+
+        return resolvedType;
+    }
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/types/TypeComparator.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/types/TypeComparator.java
index efe7dc3..d1fa386 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/types/TypeComparator.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/types/TypeComparator.java
@@ -76,17 +76,15 @@
                     {
                         continue CHECK_CANDIDATES;
                     }
-                    else
+
+                    final Diagnostic test =
+                        methodSignaturesMatch(curSatisfyType, testType);
+                    
+                    if (test.getSeverity() ==  Diagnostic.OK)
                     {
-                        final Diagnostic test =
-                            methodSignaturesMatch(curSatisfyType, testType);
-                        
-                        if (test.getSeverity() ==  Diagnostic.OK)
-                        {
-                            result = Diagnostic.OK_INSTANCE;
-                            // found a match so break
-                            break MAIN_LOOP;
-                        }
+                        result = Diagnostic.OK_INSTANCE;
+                        // found a match so break
+                        break MAIN_LOOP;
                     }
                 }