package annotator.find;

import annotator.scanner.InstanceOfScanner;

import com.sun.source.tree.InstanceOfTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreePath;

public class InstanceOfCriterion implements Criterion {

  private String methodName;
  private Integer offset;

  public InstanceOfCriterion(String methodName, Integer offset) {
    this.methodName = methodName.substring(0, methodName.lastIndexOf(")") + 1);
    this.offset = offset;
  }

  /** {@inheritDoc} */
  @Override
  public boolean isSatisfiedBy(TreePath path, Tree leaf) {
    assert path == null || path.getLeaf() == leaf;
    return isSatisfiedBy(path);
  }

  /** {@inheritDoc} */
  @Override
  public boolean isSatisfiedBy(TreePath path) {
    if (path == null) {
      debug("return null");
      return false;
    }

    Tree leaf = path.getLeaf();

    debug("");
    debug(this.toString());
    debug("InstanceOfCriterion.isSatisfiedBy: " + leaf);
    debug("leaf: " + leaf);
    debug("kind: " + leaf.getKind());
    debug("class: " + leaf.getClass());

    TreePath parentPath = path.getParentPath();
    if (parentPath == null) {
      debug("return: parent path null");
      return false;
    }

    Tree parent = parentPath.getLeaf();
    if (parent == null) {
      debug("return: parent null");
      return false;
    }

    if (parent.getKind() == Tree.Kind.INSTANCE_OF) {
      InstanceOfTree instanceOfTree = (InstanceOfTree) parent;
      if (leaf != instanceOfTree.getType()) {
        debug("return: not type part of instanceof");
        return false;
      }

      int indexInSource = InstanceOfScanner.indexOfInstanceOfTree(path, parent);
      int indexInClass = InstanceOfScanner.getMethodInstanceOfIndex(methodName, offset);
      boolean b = (indexInSource == indexInClass);
      debug("return source: "+ indexInSource);
      debug("return class: " + indexInClass);
      debug("return new: " + b);
      return b;
    } else {
      boolean b = this.isSatisfiedBy(path.getParentPath());
      debug("return parent: " + b);
      return b;
    }
  }

  public Kind getKind() {
    return Kind.INSTANCE_OF;
  }

  private static void debug(String s) {
    if (Criteria.debug) {
      System.out.println(s);
    }
  }

  public String toString() {
    return "InstanceOfCriterion: in method: " + methodName + " offset: " + offset;
  }

}

@@ -18,16 +18,56 @@
 .find;%0A%0A
+import annotations.el.RelativeLocation;%0A
 import a
@@ -313,30 +313,36 @@
 private 
-Integer offset
+RelativeLocation loc
 ;%0A%0A  pub
@@ -388,22 +388,28 @@
 me, 
-Integer offset
+RelativeLocation loc
 ) %7B%0A
@@ -501,23 +501,17 @@
 his.
-offset = offset
+loc = loc
 ;%0A  
@@ -1702,24 +1702,125 @@
 ent);%0A      
+debug(%22return source: %22+ indexInSource);%0A      boolean b;%0A      if (loc.isBytecodeOffset()) %7B%0A    %09  
 int indexInC
@@ -1881,16 +1881,20 @@
 odName, 
+loc.
 offset);
@@ -1904,100 +1904,156 @@
     
-boolean b = (indexInSource == indexInClass);%0A      debug(%22return source: %22+ indexInSource);%0A
+    debug(%22return class: %22 + indexInClass);%0A    %09  b = (indexInSource == indexInClass);%0A      %7D else %7B%0A    %09  b = (indexInSource == loc.index);%0A    
     
@@ -2072,33 +2072,42 @@
 urn 
-class
+loc.index
 : %22 + 
+loc.
 index
-InClass);
+);%0A      %7D
 %0A   
@@ -2550,26 +2550,25 @@
 + %22 
-offset: %22 + offset
+location: %22 + loc
 ;%0A  

Use the new RelativeLocation instead of plain Integers.