import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Writer;

import java.net.URI;

import java.util.ArrayList;
import java.util.List;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;

public class Class1
{
  private static boolean writeOneFile(String content, File testFile)
  {
    FileOutputStream stream = null;
    try
    {
      try
      {
        stream = new FileOutputStream(testFile);
        stream.write(content.getBytes());
      }
      finally
      {
        if (stream != null)
          stream.close();
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
      return false;
    }
    return true;
  }

  private static JavaFileManager getJavaFileManager(JavaCompiler compiler,
                                                    DiagnosticCollector dc)
  {
    return compiler.getStandardFileManager(dc, null, null);
  }

  static public JavaFileObject getJavaFileObject(URI uri, final String code)
  {
    return new SimpleJavaFileObject(uri, JavaFileObject.Kind.SOURCE)
    {
      public boolean isNameCompatible(String simpleName, Kind kind)
      {
        return true;
      }
      public CharSequence getCharContent(boolean ignoreEncodingErrors) throws
IOException
      {
        return code;
      }
    };
  }

  public static void main(String[] args)
  {
    try
    {
      File source = File.createTempFile( "Bug", ".java" );
      source.deleteOnExit();
      String name = source.getName();
      int index = name.lastIndexOf('.');
      name = name.substring(0, index);
      StringBuilder code = new StringBuilder();
      code.append( "public class " );
      code.append( name );
      code.append( "{ Object o = new A().new B(); class A { } }" );
      File tempDir = source.getParentFile();
      Class1.writeOneFile( code.toString(), source );
      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
      Writer writer = new Writer()
      {
        public void write(char[] cbuf, int off, int len)
        {
          System.out.println( cbuf );
        }
        public void flush() {}
        public void close() {}
      };
      DiagnosticCollector dc = new DiagnosticCollector();
      JavaFileManager javaFileManager = getJavaFileManager(compiler, dc);
      List<String> options = new ArrayList<String>();
      options.add( "-cp" );
      options.add( tempDir.getPath() );
      options.add( "-d" );
      options.add( tempDir.getPath() );
      List<JavaFileObject> sources = new ArrayList<JavaFileObject>();
      sources.add( getJavaFileObject(source.toURI(), code.toString()) );
      JavaCompiler.CompilationTask task =
        compiler.getTask(writer, javaFileManager,
                         dc, options, null,
                         sources);
      task.call();
      for ( Diagnostic diagnostic : (List<Diagnostic>)dc.getDiagnostics() )
      {
        System.out.println("StartPosition: " + diagnostic.getStartPosition());
        System.out.println("EndPosition: " + diagnostic.getEndPosition());
        System.out.println("Diagnostic: " + diagnostic.getClass());
        System.out.println("Diagnostic: " + diagnostic);
      }
    }
    catch ( Exception ex )
    {
      ex.printStackTrace();
    }
  }
}