aspect traversal1 {
  void A. t() {
      b.t(); c.t();
  }

  void B.t() {
    d.t(); e.t();
  }
  void C.t() {}
  void D.t() {
     System.out.println(" in D-object direct ");
  }
  void E.t() {
     System.out.println(" in E-object direct ");
  }
}

aspect visitor {
  // advising traversal traversal1
  before() : execution(void D.t()) {
  // before() : call(void D.t()) {
    System.out.println(" in D-object ");
  } 
  before() : execution(void E.t()) {
  // before() : call(void E.t()) {
    System.out.println(" in E-object ");
  } 
  before() : call(void D.t()) {
    Object thiz = thisJoinPoint.getThis();
    Object target = thisJoinPoint.getTarget();
    System.out.println("target = " + target +
		       "this ="    + thiz);
  }
}

aspect FoundD{
  Object caller;
  void around():call(void *.t()) {
    Object savedCaller = caller;
    caller = thisJoinPoint.getThis();
    proceed();
    caller = savedCaller;
  }
  void around() : execution(void D.t()) {
    System.out.println(" ryan " + thisJoinPoint.getThis());
    System.out.println(" ryan " + caller.toString());
  }
}

aspect Jeff{
  before() : call(void *.t()){
    Object thiz = thisJoinPoint.getThis();
    Object target = thisJoinPoint.getTarget();
    if(target instanceof D){
          System.out.println("JEFF target = " + target +
                       "this ="    + thiz);
    }
  }
}

class A {
  B b;
  C c;
  A(B b, C c){ this.b = b; this.c = c;}
}

class B {
  D d;
  E e;
  B(D d, E e) {this.d = d; this.e = e;}
}

class C {
}

class D extends C {
}

class E extends C {
}

class Main {
  static public void main(String args[]) {
    A a_in = new A(new B(new D(), new E()), new D());
    a_in.t();
  }
}  

