@Override
	public AMethodMeta choosingTheMostSpecificMethod(List<AMethodMeta> entities) {
		Set<AMethodMeta> most = null;
		for(AMethodMeta e : entities){
			if(CollectionUtils.isEmpty(most)){
				most = new HashSet<>();
				most.add(e);
			}else{
				Set<AMethodMeta> newMost = new HashSet<>();
				for(AMethodMeta mostE : most){
					CollectionUtils.addAll(newMost, mostSpecificMethod(mostE, e));
				}
				most = newMost;
			}
		}
		
		int mostLen = most == null ? 0 : most.size();
        if(mostLen > 1) {
            //first remove varargs method and re add to potentially
            //in order to third phase choose.
            Set<AMethodMeta> newMost = new HashSet<>();
            for(AMethodMeta m : most){
                if(!Modifiers.isVarargs(m.getModifiers())) {
                    newMost.add(m);
                }
            }
            most = newMost;
        }
		
		if(CollectionUtils.isNotEmpty(most)){
			if(most.size() == 1){
				return (AMethodMeta) most.toArray()[0];
			}else{
				String argTypes = ArrayUtils.toString(argumentTypes);
				throw new IllegalArgumentException("The method invocation is ambiguous: " + name + "(" + argTypes.substring(1, argTypes.length() - 1) + ")");
			}
		}
		return null;
	}