@Override
 public Collection<Goal> prerequisiteGoals(Scheduler scheduler) {
   List<Goal> l = new ArrayList<>();
   l.add(scheduler.Disambiguated(job));
   l.addAll(super.prerequisiteGoals(scheduler));
   return l;
 }
  public Node leave(Node old, Node n, NodeVisitor v) {
    n = super.leave(old, n, v);

    X10DelegatingVisitor d =
        new X10DelegatingVisitor() {
          //			public void visit(Node n) {
          //				if (n.ext() instanceof X10Ext) {
          //					for (Iterator<AnnotationNode> i = ((X10Ext) n.ext()).annotations().iterator();
          // i.hasNext(); ) {
          //						AnnotationNode an = i.next();
          //					}
          //				}
          //				super.visit(n);
          //			}

          protected void force(List l) {
            for (Iterator i = l.iterator(); i.hasNext(); ) {
              TypeObject o = (TypeObject) i.next();
              force(o);
            }
          }

          protected void force(TypeObject o) {
            if (o instanceof X10TypeObject) {
              X10TypeObject xo = (X10TypeObject) o;

              if (xo instanceof FieldInstance) {
                FieldInstance fi = (FieldInstance) xo;
                fi.constantValue();
                force(fi.type());
              } else if (xo instanceof LocalInstance) {
                LocalInstance li = (LocalInstance) xo;
                li.constantValue();
                force(li.type());
              } else if (xo instanceof MethodInstance) {
                MethodInstance mi = (MethodInstance) xo;
                force(mi.returnType());
                force(mi.formalTypes());
                force(mi.throwTypes());
              } else if (xo instanceof X10ConstructorInstance) {
                X10ConstructorInstance ci = (X10ConstructorInstance) xo;
                force(ci.returnType());
                force(ci.formalTypes());
                force(ci.throwTypes());
              } else if (xo instanceof ArrayType) {
                ArrayType at = (ArrayType) xo;
                force(at.base());
              } else if (xo instanceof X10ClassType) {
                X10ClassType ct = (X10ClassType) xo;
                DepParameterExpr dep = ct.dep();
                if (dep != null) {
                  dep.visit(PropagateDependentAnnotationsVisitor.this);
                }
                if (ct instanceof X10ParsedClassType) {
                  force(((X10ParsedClassType) ct).classAnnotations());
                }
                //						force(ct.superType());
                //						force(ct.interfaces());
                //						force(ct.members());
              } else if (xo instanceof ClassType) {
                ClassType ct = (ClassType) xo;
                //						force(ct.superType());
                //						force(ct.interfaces());
                //						force(ct.members());
              }

              if (xo instanceof X10ParsedClassType) {
                X10ParsedClassType ct = (X10ParsedClassType) xo;
                if (ct.job() == PropagateDependentAnnotationsVisitor.this.job()) {
                  ct.setDefAnnotations(Collections.EMPTY_LIST);
                  if (ct.isRootType()) ct.setClassAnnotations(Collections.EMPTY_LIST);
                  return;
                }
                if (ct.job() == null) {
                  ct.setDefAnnotations(Collections.EMPTY_LIST);
                  if (ct.isRootType()) ct.setClassAnnotations(Collections.EMPTY_LIST);
                  return;
                }
              } else if (xo instanceof MemberInstance) {
                MemberInstance mi = (MemberInstance) xo;
                boolean isRoot = false;
                if (mi instanceof X10FieldInstance && ((X10FieldInstance) mi).orig() == mi)
                  isRoot = true;
                if (mi instanceof X10LocalInstance && ((X10LocalInstance) mi).orig() == mi)
                  isRoot = true;
                if (mi instanceof X10MethodInstance && ((X10MethodInstance) mi).orig() == mi)
                  isRoot = true;
                if (mi instanceof X10ConstructorInstance
                    && ((X10ConstructorInstance) mi).orig() == mi) isRoot = true;
                if (mi.container() instanceof ParsedClassType) {
                  ParsedClassType ct = (ParsedClassType) mi.container();
                  if (ct.job() == PropagateDependentAnnotationsVisitor.this.job()) {
                    if (isRoot) {
                      xo.setDefAnnotations(Collections.EMPTY_LIST);
                    }
                    return;
                  }
                  if (ct.job() == null) {
                    if (isRoot) {
                      xo.setDefAnnotations(Collections.EMPTY_LIST);
                    }
                    return;
                  }
                }
              } else {
                return;
              }

              force(xo.defAnnotations());
            }
          }

          @Override
          public void visit(Call_c n) {
            force(n.methodInstance());
            super.visit(n);
          }

          @Override
          public void visit(ClassDecl_c n) {
            force(n.type());
            super.visit(n);
          }

          @Override
          public void visit(ConstructorCall_c n) {
            force(n.constructorInstance());
            super.visit(n);
          }

          @Override
          public void visit(ConstructorDecl_c n) {
            force(n.constructorInstance());
            super.visit(n);
          }

          @Override
          public void visit(Expr_c n) {
            force(n.type());
            super.visit(n);
          }

          @Override
          public void visit(Field_c n) {
            force(n.fieldInstance());
            super.visit(n);
          }

          @Override
          public void visit(FieldDecl_c n) {
            force(n.fieldInstance());
            super.visit(n);
          }

          @Override
          public void visit(Formal_c n) {
            force(n.localDef());
            super.visit(n);
          }

          // @Override
          // public void visit(Import_c n) {
          // super.visit(n);
          // }

          @Override
          public void visit(Initializer_c n) {
            force(n.initializerInstance());
            super.visit(n);
          }

          @Override
          public void visit(Local_c n) {
            force(n.localInstance());
            super.visit(n);
          }

          @Override
          public void visit(LocalDecl_c n) {
            force(n.localDef());
            super.visit(n);
          }

          @Override
          public void visit(MethodDecl_c n) {
            force(n.methodInstance());
            super.visit(n);
          }

          @Override
          public void visit(New_c n) {
            force(n.constructorInstance());
            super.visit(n);
          }

          @Override
          public void visit(PackageNode_c n) {
            force(n.package_());
            super.visit(n);
          }

          @Override
          public void visit(TypeNode_c n) {
            force(n.type());
            super.visit(n);
          }
        };

    try {
      d.visitAppropriate(n);
    } catch (MissingDependencyException e) {
      if (Report.should_report(Report.frontend, 3)) e.printStackTrace();
      Scheduler scheduler = job.extensionInfo().scheduler();
      Goal g = scheduler.currentGoal();
      scheduler.addDependencyAndEnqueue(g, e.goal(), e.prerequisite());
      g.setUnreachableThisRun();
    }

    return n;
  }
 public static Goal create(Scheduler scheduler, Job job, TypeSystem ts, NodeFactory nf) {
   return scheduler.internGoal(new TypeChecked(job, ts, nf));
 }