private void scan(
      GroovyParserResult result,
      ASTNode node,
      AstPath path,
      String in,
      Set<String> includes,
      ASTElement parent) {
    if (node instanceof AnnotatedNode && !((AnnotatedNode) node).hasNoRealSourcePosition()) {

      if (node instanceof ClassNode) {
        ASTClass co = new ASTClass(result, node);
        co.setFqn(((ClassNode) node).getName());

        if (parent != null) {
          parent.addChild(co);
        } else {
          structure.add(co);
        }

        parent = co;
      } else if (node instanceof FieldNode) {
        if (parent instanceof ASTClass) {
          // We don't have unique declarations, only assignments (possibly many)
          // so stash these in a map and extract unique fields when we're done
          Set<FieldNode> assignments = fields.get(parent);

          if (assignments == null) {
            assignments = new HashSet<FieldNode>();
            fields.put((ASTClass) parent, assignments);
          }

          assignments.add((FieldNode) node);
        }
      } else if (node instanceof MethodNode) {
        ASTMethod co = new ASTMethod(result, node);
        methods.add(co);
        co.setIn(in);

        // TODO - don't add this to the top level! Make a nested list
        if (parent != null) {
          parent.addChild(co);
        } else {
          structure.add(co);
        }
      } else if (node instanceof PropertyNode) {
        Set<PropertyNode> declarations = properties.get(parent);

        if (declarations == null) {
          declarations = new HashSet<PropertyNode>();
          properties.put((ASTClass) parent, declarations);
        }

        declarations.add((PropertyNode) node);
      }
    }

    @SuppressWarnings("unchecked")
    List<ASTNode> list = ASTUtils.children(node);

    for (ASTNode child : list) {
      path.descend(child);
      scan(result, child, path, in, includes, parent);
      path.ascend();
    }
  }