import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Scope;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TreePath;
import com.sun.source.util.Trees;
import com.sun.tools.javac.code.Symbol;
import java.net.URI;
import java.util.stream.Stream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.Element;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import java.util.stream.StreamSupport;
import java.util.stream.Collectors;

class TestConcurrent {
    public static void main(String[] args) throws Exception {
        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
        assert tool != null;
        final JavacTask ct = (JavacTask)tool.getTask(null, null, null, null, null, Arrays.asList(new MyFileObject()));

        CompilationUnitTree cut = ct.parse().iterator().next();
        TreePath tp = new TreePath(new TreePath(cut), cut.getTypeDecls().get(0));
        Scope s = Trees.instance(ct).getScope(tp);
        System.err.println(of(scopeIt(s)).flatMap(s2 -> of((Iterable<Element>)s2.getLocalElements())).map(TestConcurrent::handleElement).collect(Collectors.joining("\n")));
System.err.println("----after----");
        System.err.println(of(scopeIt(s)).flatMap(s2 -> of((Iterable<Element>)s2.getLocalElements())).map(TestConcurrent::handleElement).collect(Collectors.joining("\n")));
    }

	static String handleElement(Element e) {
		return String.format("element = %s ; completed = %s", e.toString(), ((Symbol)e).completer.isTerminal());
    }

    static <Z> Stream<Z> of(Iterable<Z> it) {
		return StreamSupport.stream(it.spliterator(), false);
    }

    static Iterable<Scope> scopeIt(Scope scope) {
		return () -> new Iterator<Scope>() {
            private Scope currentScope = scope;
            @Override
            public boolean hasNext() {
                return currentScope != null;
            }
            @Override
            public Scope next() {
                if (!hasNext())
                    throw new NoSuchElementException();
                try {
                    return currentScope;
                } finally {
                    currentScope = currentScope.getEnclosingScope();
                }
            }
        };
    }

    static class MyFileObject extends SimpleJavaFileObject {
        public MyFileObject() {
            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
        }
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return "import java.util.concurrent.*; public class Test { }";
        }
    }
}

