code: package us.msu.cse.repair.core.parser.ingredient;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  import org.eclipse.jdt.core.dom.ASTNode;
  import org.eclipse.jdt.core.dom.Statement;
  
  import us.msu.cse.repair.core.parser.MethodInfo;
  import us.msu.cse.repair.core.parser.ModificationPoint;
  import us.msu.cse.repair.core.parser.SeedStatement;
  import us.msu.cse.repair.core.parser.SeedStatementInfo;
  import us.msu.cse.repair.core.parser.StatementInfoExtractor;
  import us.msu.cse.repair.core.util.visitors.MethodConvASTVisitor;
  
  public class MethodTypeMatchIngredientScreener extends AbstractIngredientScreener {
  
  	public MethodTypeMatchIngredientScreener(List<ModificationPoint> modificationPoints,
  			Map<SeedStatement, SeedStatementInfo> seedStatements, IngredientMode ingredientMode) {
  		super(modificationPoints, seedStatements, ingredientMode);
  		// TODO Auto-generated constructor stub
  	}
  
  	@Override
  	protected void screenIngredients(ModificationPoint mp, IngredientMode ingredientMode, boolean includeSelf) {
  		// TODO Auto-generated method stub
  		Set<SeedStatement> ingredientSet = new HashSet<SeedStatement>();
  		for (Map.Entry<SeedStatement, SeedStatementInfo> entry : seedStatements.entrySet()) {
  			if (canPreFiltered(mp, entry, ingredientMode, includeSelf))
  				continue;
  
  			Statement seed = entry.getKey().getStatement();
  			seed = getMethodTypeMatchedStatement(seed, mp);
  			if (seed != null) {
  				ingredientSet.add(new SeedStatement(seed));
  			}
  		}
  
  		List<Statement> ingredients = new ArrayList<Statement>();
  		for (SeedStatement seedStatement : ingredientSet)
  			ingredients.add(seedStatement.getStatement());
  
  		mp.setIngredients(ingredients);
  	}
  
  	Statement getMethodTypeMatchedStatement(Statement seed, ModificationPoint mp) {
  		StatementInfoExtractor sie = new StatementInfoExtractor(seed);
  		sie.extract();
  
  		Map<String, MethodInfo> thisMethods = sie.getThisMethods();
  		Map<String, MethodInfo> superMethods = sie.getSuperMethods();
  		Map<String, MethodInfo> methods = sie.getMethods();
  
  		Map<String, String> methodMatchMap = new HashMap<String, String>();
  		Map<String, String> thisMethodMatchMap = new HashMap<String, String>();
  		Map<String, String> superMethodMatchMap = new HashMap<String, String>();
  
  		Map<String, MethodInfo> declaredMethods = new HashMap<String, MethodInfo>(mp.getDeclaredMethods());
  		Map<String, MethodInfo> inheritedMethods = new HashMap<String, MethodInfo>(mp.getInheritedMethods());
  		Map<String, MethodInfo> outerMethods = new HashMap<String, MethodInfo>(mp.getOuterMethods());
  
  		if (IngredientUtil.isInVarScope(seed, mp, sie)) {
  			IngredientUtil.findSuperMethods(superMethods, inheritedMethods);
  			IngredientUtil.findThisMethods(thisMethods, declaredMethods, inheritedMethods);
  			IngredientUtil.findMethods(methods, declaredMethods, inheritedMethods, outerMethods);
  
  			if (!IngredientUtil.doSuperMethodMatch(superMethodMatchMap, superMethods, inheritedMethods))
  				return null;
  			else if (!IngredientUtil.doThisMethodMatch(thisMethodMatchMap, thisMethods, declaredMethods,
  					inheritedMethods))
  				return null;
  			else if (!IngredientUtil.doMethodMatch(methodMatchMap, methods, declaredMethods, inheritedMethods,
  					outerMethods))
  				return null;
  			else if (methodMatchMap.size() > 0 || thisMethodMatchMap.size() > 0 || superMethodMatchMap.size() > 0) {
  				seed = (Statement) ASTNode.copySubtree(seed.getAST(), seed);
  				MethodConvASTVisitor visitor = new MethodConvASTVisitor(methodMatchMap, thisMethodMatchMap,
  						superMethodMatchMap, sie.getMethodIDs(), sie.getSuperMethodIDs());
  				seed.accept(visitor);
  			}
  			return seed;
  		} else
  			return null;
  	}
  
  }
  