Merge
authortbell
Wed, 25 Jun 2008 23:30:55 -0700
changeset 814 3d9921c0b40c
parent 734 d42dc41ddc74 (current diff)
parent 813 ab91293d33f4 (diff)
child 815 bcb5c0d7c1ab
Merge
langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexEntry.java
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Jun 25 23:30:55 2008 -0700
@@ -100,9 +100,12 @@
 
         boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
         boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
+        boolean enforceMandatoryWarnings = source.enforceMandatoryWarnings();
 
-        deprecationHandler = new MandatoryWarningHandler(log,verboseDeprecated, "deprecated");
-        uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked, "unchecked");
+        deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated,
+                enforceMandatoryWarnings, "deprecated");
+        uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
+                enforceMandatoryWarnings, "unchecked");
     }
 
     /** Switch: generics enabled?
@@ -1367,13 +1370,47 @@
                         types.isSameType(rt1, rt2) ||
                         rt1.tag >= CLASS && rt2.tag >= CLASS &&
                         (types.covariantReturnType(rt1, rt2, Warner.noWarnings) ||
-                         types.covariantReturnType(rt2, rt1, Warner.noWarnings));
+                         types.covariantReturnType(rt2, rt1, Warner.noWarnings)) ||
+                         checkCommonOverriderIn(s1,s2,site);
                     if (!compat) return s2;
                 }
             }
         }
         return null;
     }
+    //WHERE
+    boolean checkCommonOverriderIn(Symbol s1, Symbol s2, Type site) {
+        Map<TypeSymbol,Type> supertypes = new HashMap<TypeSymbol,Type>();
+        Type st1 = types.memberType(site, s1);
+        Type st2 = types.memberType(site, s2);
+        closure(site, supertypes);
+        for (Type t : supertypes.values()) {
+            for (Scope.Entry e = t.tsym.members().lookup(s1.name); e.scope != null; e = e.next()) {
+                Symbol s3 = e.sym;
+                if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue;
+                Type st3 = types.memberType(site,s3);
+                if (types.overrideEquivalent(st3, st1) && types.overrideEquivalent(st3, st2)) {
+                    if (s3.owner == site.tsym) {
+                        return true;
+                    }
+                    List<Type> tvars1 = st1.getTypeArguments();
+                    List<Type> tvars2 = st2.getTypeArguments();
+                    List<Type> tvars3 = st3.getTypeArguments();
+                    Type rt1 = st1.getReturnType();
+                    Type rt2 = st2.getReturnType();
+                    Type rt13 = types.subst(st3.getReturnType(), tvars3, tvars1);
+                    Type rt23 = types.subst(st3.getReturnType(), tvars3, tvars2);
+                    boolean compat =
+                        rt13.tag >= CLASS && rt23.tag >= CLASS &&
+                        (types.covariantReturnType(rt13, rt1, Warner.noWarnings) &&
+                         types.covariantReturnType(rt23, rt2, Warner.noWarnings));
+                    if (compat)
+                        return true;
+                }
+            }
+        }
+        return false;
+    }
 
     /** Check that a given method conforms with any method it overrides.
      *  @param tree         The tree from which positions are extracted
--- a/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/BaseFileObject.java	Wed Jun 25 23:30:55 2008 -0700
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javac.file;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.Reader;
@@ -36,6 +37,9 @@
 import static javax.tools.JavaFileObject.Kind.*;
 
 public abstract class BaseFileObject implements JavaFileObject {
+    protected BaseFileObject(JavacFileManager fileManager) {
+        this.fileManager = fileManager;
+    }
 
     public JavaFileObject.Kind getKind() {
         String n = getName();
@@ -76,4 +80,14 @@
         throw new UnsupportedOperationException();
     }
 
+    protected abstract String inferBinaryName(Iterable<? extends File> path);
+
+    protected static String removeExtension(String fileName) {
+        int lastDot = fileName.lastIndexOf(".");
+        return (lastDot == -1 ? fileName : fileName.substring(0, lastDot));
+    }
+
+    /** The file manager that created this JavaFileObject. */
+    protected final JavacFileManager fileManager;
+
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Wed Jun 25 23:30:55 2008 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,21 +25,16 @@
 
 package com.sun.tools.javac.file;
 
-import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.OutputStreamWriter;
-import java.io.Writer;
 import java.lang.ref.SoftReference;
 import java.net.MalformedURLException;
 import java.net.URI;
-import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.nio.ByteBuffer;
@@ -56,13 +51,11 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
 import javax.lang.model.SourceVersion;
@@ -96,15 +89,6 @@
 
     boolean useZipFileIndex;
 
-    private static int symbolFilePrefixLength = 0;
-    static {
-        try {
-            symbolFilePrefixLength = symbolFilePrefix.getBytes("UTF-8").length;
-        } catch (java.io.UnsupportedEncodingException uee) {
-            // Can't happen...UTF-8 is always supported.
-        }
-    }
-
     private static boolean CHECK_ZIP_TIMESTAMP = false;
     private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>();
 
@@ -202,7 +186,7 @@
     }
 
     public JavaFileObject getRegularFile(File file) {
-        return new RegularFileObject(file);
+        return new RegularFileObject(this, file);
     }
 
     public JavaFileObject getFileForOutput(String classname,
@@ -405,7 +389,7 @@
                 } else {
                     if (isValidFile(fname, fileKinds)) {
                         JavaFileObject fe =
-                        new RegularFileObject(fname, new File(d, fname));
+                            new RegularFileObject(this, fname, new File(d, fname));
                         l.append(fe);
                     }
                 }
@@ -469,106 +453,13 @@
         Set<String> getSubdirectories();
     }
 
-    public class ZipArchive implements Archive {
-        protected final Map<String,List<String>> map;
-        protected final ZipFile zdir;
-        public ZipArchive(ZipFile zdir) throws IOException {
-            this.zdir = zdir;
-            this.map = new HashMap<String,List<String>>();
-            for (Enumeration<? extends ZipEntry> e = zdir.entries(); e.hasMoreElements(); ) {
-                ZipEntry entry;
-                try {
-                    entry = e.nextElement();
-                } catch (InternalError ex) {
-                    IOException io = new IOException();
-                    io.initCause(ex); // convenience constructors added in Mustang :-(
-                    throw io;
-                }
-                addZipEntry(entry);
-            }
-        }
-
-        void addZipEntry(ZipEntry entry) {
-            String name = entry.getName();
-            int i = name.lastIndexOf('/');
-            String dirname = name.substring(0, i+1);
-            String basename = name.substring(i+1);
-            if (basename.length() == 0)
-                return;
-            List<String> list = map.get(dirname);
-            if (list == null)
-                list = List.nil();
-            list = list.prepend(basename);
-            map.put(dirname, list);
-        }
-
-        public boolean contains(String name) {
-            int i = name.lastIndexOf('/');
-            String dirname = name.substring(0, i+1);
-            String basename = name.substring(i+1);
-            if (basename.length() == 0)
-                return false;
-            List<String> list = map.get(dirname);
-            return (list != null && list.contains(basename));
-        }
-
-        public List<String> getFiles(String subdirectory) {
-            return map.get(subdirectory);
-        }
-
-        public JavaFileObject getFileObject(String subdirectory, String file) {
-            ZipEntry ze = zdir.getEntry(subdirectory + file);
-            return new ZipFileObject(file, zdir, ze);
-        }
-
-        public Set<String> getSubdirectories() {
-            return map.keySet();
-        }
-
-        public void close() throws IOException {
-            zdir.close();
-        }
-    }
-
-    public class SymbolArchive extends ZipArchive {
-        final File origFile;
-        public SymbolArchive(File orig, ZipFile zdir) throws IOException {
-            super(zdir);
-            this.origFile = orig;
-        }
-
-        @Override
-        void addZipEntry(ZipEntry entry) {
-            // called from super constructor, may not refer to origFile.
-            String name = entry.getName();
-            if (!name.startsWith(symbolFilePrefix))
-                return;
-            name = name.substring(symbolFilePrefix.length());
-            int i = name.lastIndexOf('/');
-            String dirname = name.substring(0, i+1);
-            String basename = name.substring(i+1);
-            if (basename.length() == 0)
-                return;
-            List<String> list = map.get(dirname);
-            if (list == null)
-                list = List.nil();
-            list = list.prepend(basename);
-            map.put(dirname, list);
-        }
-
-        @Override
-        public JavaFileObject getFileObject(String subdirectory, String file) {
-            return super.getFileObject(symbolFilePrefix + subdirectory, file);
-        }
-    }
-
     public class MissingArchive implements Archive {
         final File zipFileName;
         public MissingArchive(File name) {
             zipFileName = name;
         }
         public boolean contains(String name) {
-              return false;
+            return false;
         }
 
         public void close() {
@@ -647,25 +538,30 @@
 
                 if (origZipFileName == zipFileName) {
                     if (!useZipFileIndex) {
-                        archive = new ZipArchive(zdir);
+                        archive = new ZipArchive(this, zdir);
                     } else {
-                        archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, 0,
+                        archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, null,
                                 usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null));
                     }
                 }
                 else {
                     if (!useZipFileIndex) {
-                        archive = new SymbolArchive(origZipFileName, zdir);
+                        archive = new SymbolArchive(this, origZipFileName, zdir, symbolFilePrefix);
                     }
                     else {
-                        archive = new ZipFileIndexArchive(this, ZipFileIndex.getZipFileIndex(zipFileName, symbolFilePrefixLength,
-                                usePreindexedCache, preindexCacheLocation, options.get("writezipindexfiles") != null));
+                        archive = new ZipFileIndexArchive(this,
+                                ZipFileIndex.getZipFileIndex(zipFileName,
+                                symbolFilePrefix,
+                                usePreindexedCache,
+                                preindexCacheLocation,
+                                options.get("writezipindexfiles") != null));
                     }
                 }
             } catch (FileNotFoundException ex) {
                 archive = new MissingArchive(zipFileName);
             } catch (IOException ex) {
-                log.error("error.reading.file", zipFileName, ex.getLocalizedMessage());
+                if (zipFileName.exists())
+                    log.error("error.reading.file", zipFileName, ex.getLocalizedMessage());
                 archive = new MissingArchive(zipFileName);
             }
 
@@ -694,7 +590,17 @@
         }
     }
 
-    private Map<JavaFileObject, SoftReference<CharBuffer>> contentCache = new HashMap<JavaFileObject, SoftReference<CharBuffer>>();
+    CharBuffer getCachedContent(JavaFileObject file) {
+        SoftReference<CharBuffer> r = contentCache.get(file);
+        return (r == null ? null : r.get());
+    }
+
+    void cache(JavaFileObject file, CharBuffer cb) {
+        contentCache.put(file, new SoftReference<CharBuffer>(cb));
+    }
+
+    private final Map<JavaFileObject, SoftReference<CharBuffer>> contentCache
+            = new HashMap<JavaFileObject, SoftReference<CharBuffer>>();
 
     private String defaultEncodingName;
     private String getDefaultEncodingName() {
@@ -724,7 +630,7 @@
     /**
      * Make a byte buffer from an input stream.
      */
-    private ByteBuffer makeByteBuffer(InputStream in)
+    ByteBuffer makeByteBuffer(InputStream in)
         throws IOException {
         int limit = in.available();
         if (mmappedIO && in instanceof FileInputStream) {
@@ -750,6 +656,10 @@
         return (ByteBuffer)result.flip();
     }
 
+    void recycleByteBuffer(ByteBuffer bb) {
+        byteBufferCache.put(bb);
+    }
+
     /**
      * A single-element cache of direct byte buffers.
      */
@@ -768,9 +678,10 @@
             cached = x;
         }
     }
+
     private final ByteBufferCache byteBufferCache;
 
-    private CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) {
+    CharsetDecoder getDecoder(String encodingName, boolean ignoreEncodingErrors) {
         Charset charset = (this.charset == null)
             ? Charset.forName(encodingName)
             : this.charset;
@@ -790,7 +701,7 @@
     /**
      * Decode a ByteBuffer into a CharBuffer.
      */
-    private CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) {
+    CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) {
         String encodingName = getEncodingName();
         CharsetDecoder decoder;
         try {
@@ -900,48 +811,14 @@
         // Need to match the path semantics of list(location, ...)
         Iterable<? extends File> path = getLocation(location);
         if (path == null) {
-            //System.err.println("Path for " + location + " is null");
             return null;
         }
-        //System.err.println("Path for " + location + " is " + path);
 
-        if (file instanceof RegularFileObject) {
-            RegularFileObject r = (RegularFileObject) file;
-            String rPath = r.getPath();
-            //System.err.println("RegularFileObject " + file + " " +r.getPath());
-            for (File dir: path) {
-                //System.err.println("dir: " + dir);
-                String dPath = dir.getPath();
-                if (!dPath.endsWith(File.separator))
-                    dPath += File.separator;
-                if (rPath.regionMatches(true, 0, dPath, 0, dPath.length())
-                    && new File(rPath.substring(0, dPath.length())).equals(new File(dPath))) {
-                    String relativeName = rPath.substring(dPath.length());
-                    return removeExtension(relativeName).replace(File.separatorChar, '.');
-                }
-            }
-        } else if (file instanceof ZipFileObject) {
-            ZipFileObject z = (ZipFileObject) file;
-            String entryName = z.getZipEntryName();
-            if (entryName.startsWith(symbolFilePrefix))
-                entryName = entryName.substring(symbolFilePrefix.length());
-            return removeExtension(entryName).replace('/', '.');
-        } else if (file instanceof ZipFileIndexFileObject) {
-            ZipFileIndexFileObject z = (ZipFileIndexFileObject) file;
-            String entryName = z.getZipEntryName();
-            if (entryName.startsWith(symbolFilePrefix))
-                entryName = entryName.substring(symbolFilePrefix.length());
-            return removeExtension(entryName).replace(File.separatorChar, '.');
+        if (file instanceof BaseFileObject) {
+            return ((BaseFileObject) file).inferBinaryName(path);
         } else
             throw new IllegalArgumentException(file.getClass().getName());
-        // System.err.println("inferBinaryName failed for " + file);
-        return null;
     }
-    // where
-        private static String removeExtension(String fileName) {
-            int lastDot = fileName.lastIndexOf(".");
-            return (lastDot == -1 ? fileName : fileName.substring(0, lastDot));
-        }
 
     public boolean isSameFile(FileObject a, FileObject b) {
         nullCheck(a);
@@ -1028,7 +905,7 @@
             if (dir.isDirectory()) {
                 File f = new File(dir, name.replace('/', File.separatorChar));
                 if (f.exists())
-                    return new RegularFileObject(f);
+                    return new RegularFileObject(this, f);
             } else {
                 Archive a = openArchive(dir);
                 if (a.contains(name)) {
@@ -1090,7 +967,7 @@
                 if (sibling != null && sibling instanceof RegularFileObject) {
                     siblingDir = ((RegularFileObject)sibling).f.getParentFile();
                 }
-                return new RegularFileObject(new File(siblingDir, baseName(fileName)));
+                return new RegularFileObject(this, new File(siblingDir, baseName(fileName)));
             }
         } else if (location == SOURCE_OUTPUT) {
             dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir());
@@ -1104,7 +981,7 @@
         }
 
         File file = (dir == null ? new File(fileName) : new File(dir, fileName));
-        return new RegularFileObject(file);
+        return new RegularFileObject(this, file);
 
     }
 
@@ -1117,7 +994,7 @@
         else
             result = new ArrayList<RegularFileObject>();
         for (File f: files)
-            result.add(new RegularFileObject(nullCheck(f)));
+            result.add(new RegularFileObject(this, nullCheck(f)));
         return result;
     }
 
@@ -1267,452 +1144,4 @@
             t.getClass(); // null check
         return it;
     }
-
-    /**
-     * A subclass of JavaFileObject representing regular files.
-     */
-    private class RegularFileObject extends BaseFileObject {
-        /** Have the parent directories been created?
-         */
-        private boolean hasParents=false;
-
-        /** The file's name.
-         */
-        private String name;
-
-        /** The underlying file.
-         */
-        final File f;
-
-        public RegularFileObject(File f) {
-            this(f.getName(), f);
-        }
-
-        public RegularFileObject(String name, File f) {
-            if (f.isDirectory())
-                throw new IllegalArgumentException("directories not supported");
-            this.name = name;
-            this.f = f;
-        }
-
-        public InputStream openInputStream() throws IOException {
-            return new FileInputStream(f);
-        }
-
-        protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
-            return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors);
-        }
-
-        public OutputStream openOutputStream() throws IOException {
-            ensureParentDirectoriesExist();
-            return new FileOutputStream(f);
-        }
-
-        public Writer openWriter() throws IOException {
-            ensureParentDirectoriesExist();
-            return new OutputStreamWriter(new FileOutputStream(f), getEncodingName());
-        }
-
-        private void ensureParentDirectoriesExist() throws IOException {
-            if (!hasParents) {
-                File parent = f.getParentFile();
-                if (parent != null && !parent.exists()) {
-                    if (!parent.mkdirs()) {
-                        // if the mkdirs failed, it may be because another process concurrently
-                        // created the directory, so check if the directory got created
-                        // anyway before throwing an exception
-                        if (!parent.exists() || !parent.isDirectory())
-                            throw new IOException("could not create parent directories");
-                    }
-                }
-                hasParents = true;
-            }
-        }
-
-        /** @deprecated see bug 6410637 */
-        @Deprecated
-        public String getName() {
-            return name;
-        }
-
-        public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) {
-            cn.getClass(); // null check
-            if (kind == Kind.OTHER && getKind() != kind)
-                return false;
-            String n = cn + kind.extension;
-            if (name.equals(n))
-                return true;
-            if (name.equalsIgnoreCase(n)) {
-                try {
-                    // allow for Windows
-                    return (f.getCanonicalFile().getName().equals(n));
-                } catch (IOException e) {
-                }
-            }
-            return false;
-        }
-
-        /** @deprecated see bug 6410637 */
-        @Deprecated
-        public String getPath() {
-            return f.getPath();
-        }
-
-        public long getLastModified() {
-            return f.lastModified();
-        }
-
-        public boolean delete() {
-            return f.delete();
-        }
-
-        public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
-            SoftReference<CharBuffer> r = contentCache.get(this);
-            CharBuffer cb = (r == null ? null : r.get());
-            if (cb == null) {
-                InputStream in = new FileInputStream(f);
-                try {
-                    ByteBuffer bb = makeByteBuffer(in);
-                    JavaFileObject prev = log.useSource(this);
-                    try {
-                        cb = decode(bb, ignoreEncodingErrors);
-                    } finally {
-                        log.useSource(prev);
-                    }
-                    byteBufferCache.put(bb); // save for next time
-                    if (!ignoreEncodingErrors)
-                        contentCache.put(this, new SoftReference<CharBuffer>(cb));
-                } finally {
-                    in.close();
-                }
-            }
-            return cb;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof RegularFileObject))
-                return false;
-            RegularFileObject o = (RegularFileObject) other;
-            try {
-                return f.equals(o.f)
-                    || f.getCanonicalFile().equals(o.f.getCanonicalFile());
-            } catch (IOException e) {
-                return false;
-            }
-        }
-
-        @Override
-        public int hashCode() {
-            return f.hashCode();
-        }
-
-        public URI toUri() {
-            try {
-                // Do no use File.toURI to avoid file system access
-                String path = f.getAbsolutePath().replace(File.separatorChar, '/');
-                return new URI("file://" + path).normalize();
-            } catch (URISyntaxException ex) {
-                return f.toURI();
-            }
-        }
-
-    }
-
-    /**
-     * A subclass of JavaFileObject representing zip entries.
-     */
-    public class ZipFileObject extends BaseFileObject {
-
-        /** The entry's name.
-         */
-        private String name;
-
-        /** The zipfile containing the entry.
-         */
-        ZipFile zdir;
-
-        /** The underlying zip entry object.
-         */
-        ZipEntry entry;
-
-        public ZipFileObject(String name, ZipFile zdir, ZipEntry entry) {
-            this.name = name;
-            this.zdir = zdir;
-            this.entry = entry;
-        }
-
-        public InputStream openInputStream() throws IOException {
-            return zdir.getInputStream(entry);
-        }
-
-        public OutputStream openOutputStream() throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
-            return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors);
-        }
-
-        public Writer openWriter() throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        /** @deprecated see bug 6410637 */
-        @Deprecated
-        public String getName() {
-            return name;
-        }
-
-        public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
-            cn.getClass(); // null check
-            if (k == Kind.OTHER && getKind() != k)
-                return false;
-            return name.equals(cn + k.extension);
-        }
-
-        /** @deprecated see bug 6410637 */
-        @Deprecated
-        public String getPath() {
-            return zdir.getName() + "(" + entry + ")";
-        }
-
-        public long getLastModified() {
-            return entry.getTime();
-        }
-
-        public boolean delete() {
-            throw new UnsupportedOperationException();
-        }
-
-        public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
-            SoftReference<CharBuffer> r = contentCache.get(this);
-            CharBuffer cb = (r == null ? null : r.get());
-            if (cb == null) {
-                InputStream in = zdir.getInputStream(entry);
-                try {
-                    ByteBuffer bb = makeByteBuffer(in);
-                    JavaFileObject prev = log.useSource(this);
-                    try {
-                        cb = decode(bb, ignoreEncodingErrors);
-                    } finally {
-                        log.useSource(prev);
-                    }
-                    byteBufferCache.put(bb); // save for next time
-                    if (!ignoreEncodingErrors)
-                        contentCache.put(this, new SoftReference<CharBuffer>(cb));
-                } finally {
-                    in.close();
-                }
-            }
-            return cb;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof ZipFileObject))
-                return false;
-            ZipFileObject o = (ZipFileObject) other;
-            return zdir.equals(o.zdir) || name.equals(o.name);
-        }
-
-        @Override
-        public int hashCode() {
-            return zdir.hashCode() + name.hashCode();
-        }
-
-        public String getZipName() {
-            return zdir.getName();
-        }
-
-        public String getZipEntryName() {
-            return entry.getName();
-        }
-
-        public URI toUri() {
-            String zipName = new File(getZipName()).toURI().normalize().getPath();
-            String entryName = getZipEntryName();
-            return URI.create("jar:" + zipName + "!" + entryName);
-        }
-
-    }
-
-    /**
-     * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.zip.ZipFileIndex implementation.
-     */
-    public class ZipFileIndexFileObject extends BaseFileObject {
-
-            /** The entry's name.
-         */
-        private String name;
-
-        /** The zipfile containing the entry.
-         */
-        ZipFileIndex zfIndex;
-
-        /** The underlying zip entry object.
-         */
-        ZipFileIndexEntry entry;
-
-        /** The InputStream for this zip entry (file.)
-         */
-        InputStream inputStream = null;
-
-        /** The name of the zip file where this entry resides.
-         */
-        String zipName;
-
-        JavacFileManager defFileManager = null;
-
-        public ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndexEntry entry, String zipFileName) {
-            super();
-            this.name = entry.getFileName();
-            this.zfIndex = zfIndex;
-            this.entry = entry;
-            this.zipName = zipFileName;
-            defFileManager = fileManager;
-        }
-
-        public InputStream openInputStream() throws IOException {
-
-            if (inputStream == null) {
-                inputStream = new ByteArrayInputStream(read());
-            }
-            return inputStream;
-        }
-
-        protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
-            return JavacFileManager.this.getDecoder(getEncodingName(), ignoreEncodingErrors);
-        }
-
-        public OutputStream openOutputStream() throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        public Writer openWriter() throws IOException {
-            throw new UnsupportedOperationException();
-        }
-
-        /** @deprecated see bug 6410637 */
-        @Deprecated
-        public String getName() {
-            return name;
-        }
-
-        public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
-            cn.getClass(); // null check
-            if (k == Kind.OTHER && getKind() != k)
-                return false;
-            return name.equals(cn + k.extension);
-        }
-
-        /** @deprecated see bug 6410637 */
-        @Deprecated
-        public String getPath() {
-            return zipName + "(" + entry.getName() + ")";
-        }
-
-        public long getLastModified() {
-            return entry.getLastModified();
-        }
-
-        public boolean delete() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (!(other instanceof ZipFileIndexFileObject))
-                return false;
-            ZipFileIndexFileObject o = (ZipFileIndexFileObject) other;
-            return entry.equals(o.entry);
-        }
-
-        @Override
-        public int hashCode() {
-            return zipName.hashCode() + (name.hashCode() << 10);
-        }
-
-        public String getZipName() {
-            return zipName;
-        }
-
-        public String getZipEntryName() {
-            return entry.getName();
-        }
-
-        public URI toUri() {
-            String zipName = new File(getZipName()).toURI().normalize().getPath();
-            String entryName = getZipEntryName();
-            if (File.separatorChar != '/') {
-                entryName = entryName.replace(File.separatorChar, '/');
-            }
-            return URI.create("jar:" + zipName + "!" + entryName);
-        }
-
-        private byte[] read() throws IOException {
-            if (entry == null) {
-                entry = zfIndex.getZipIndexEntry(name);
-                if (entry == null)
-                  throw new FileNotFoundException();
-            }
-            return zfIndex.read(entry);
-        }
-
-        public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
-            SoftReference<CharBuffer> r = defFileManager.contentCache.get(this);
-            CharBuffer cb = (r == null ? null : r.get());
-            if (cb == null) {
-                InputStream in = new ByteArrayInputStream(zfIndex.read(entry));
-                try {
-                    ByteBuffer bb = makeByteBuffer(in);
-                    JavaFileObject prev = log.useSource(this);
-                    try {
-                        cb = decode(bb, ignoreEncodingErrors);
-                    } finally {
-                        log.useSource(prev);
-                    }
-                    byteBufferCache.put(bb); // save for next time
-                    if (!ignoreEncodingErrors)
-                        defFileManager.contentCache.put(this, new SoftReference<CharBuffer>(cb));
-                } finally {
-                    in.close();
-                }
-            }
-            return cb;
-        }
-    }
-
-    public class ZipFileIndexArchive implements Archive {
-        private final ZipFileIndex zfIndex;
-        private JavacFileManager fileManager;
-
-        public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException {
-            this.fileManager = fileManager;
-            this.zfIndex = zdir;
-        }
-
-        public boolean contains(String name) {
-            return zfIndex.contains(name);
-        }
-
-        public com.sun.tools.javac.util.List<String> getFiles(String subdirectory) {
-              return zfIndex.getFiles(((subdirectory.endsWith("/") || subdirectory.endsWith("\\"))? subdirectory.substring(0, subdirectory.length() - 1) : subdirectory));
-        }
-
-        public JavaFileObject getFileObject(String subdirectory, String file) {
-            String fullZipFileName = subdirectory + file;
-            ZipFileIndexEntry entry = zfIndex.getZipIndexEntry(fullZipFileName);
-            JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile().getPath());
-            return ret;
-        }
-
-        public Set<String> getSubdirectories() {
-            return zfIndex.getAllDirectories();
-        }
-
-        public void close() throws IOException {
-            zfIndex.close();
-        }
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java	Wed Jun 25 23:30:55 2008 -0700
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.tools.javac.file;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharsetDecoder;
+import javax.tools.JavaFileObject;
+
+/**
+ * A subclass of JavaFileObject representing regular files.
+ */
+class RegularFileObject extends BaseFileObject {
+
+    /** Have the parent directories been created?
+     */
+    private boolean hasParents = false;
+    private String name;
+    final File f;
+
+    public RegularFileObject(JavacFileManager fileManager, File f) {
+        this(fileManager, f.getName(), f);
+    }
+
+    public RegularFileObject(JavacFileManager fileManager, String name, File f) {
+        super(fileManager);
+        if (f.isDirectory()) {
+            throw new IllegalArgumentException("directories not supported");
+        }
+        this.name = name;
+        this.f = f;
+    }
+
+    public InputStream openInputStream() throws IOException {
+        return new FileInputStream(f);
+    }
+
+    protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
+        return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
+    }
+
+    public OutputStream openOutputStream() throws IOException {
+        ensureParentDirectoriesExist();
+        return new FileOutputStream(f);
+    }
+
+    public Writer openWriter() throws IOException {
+        ensureParentDirectoriesExist();
+        return new OutputStreamWriter(new FileOutputStream(f), fileManager.getEncodingName());
+    }
+
+    @Override
+    protected String inferBinaryName(Iterable<? extends File> path) {
+        String fPath = f.getPath();
+        //System.err.println("RegularFileObject " + file + " " +r.getPath());
+        for (File dir: path) {
+            //System.err.println("dir: " + dir);
+            String dPath = dir.getPath();
+            if (!dPath.endsWith(File.separator))
+                dPath += File.separator;
+            if (fPath.regionMatches(true, 0, dPath, 0, dPath.length())
+                && new File(fPath.substring(0, dPath.length())).equals(new File(dPath))) {
+                String relativeName = fPath.substring(dPath.length());
+                return removeExtension(relativeName).replace(File.separatorChar, '.');
+            }
+        }
+        return null;
+    }
+
+    private void ensureParentDirectoriesExist() throws IOException {
+        if (!hasParents) {
+            File parent = f.getParentFile();
+            if (parent != null && !parent.exists()) {
+                if (!parent.mkdirs()) {
+                    if (!parent.exists() || !parent.isDirectory()) {
+                        throw new IOException("could not create parent directories");
+                    }
+                }
+            }
+            hasParents = true;
+        }
+    }
+
+    @Deprecated
+    public String getName() {
+        return name;
+    }
+
+    public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) {
+        cn.getClass();
+        // null check
+        if (kind == Kind.OTHER && getKind() != kind) {
+            return false;
+        }
+        String n = cn + kind.extension;
+        if (name.equals(n)) {
+            return true;
+        }
+        if (name.equalsIgnoreCase(n)) {
+            try {
+                // allow for Windows
+                return f.getCanonicalFile().getName().equals(n);
+            } catch (IOException e) {
+            }
+        }
+        return false;
+    }
+
+    @Deprecated
+    public String getPath() {
+        return f.getPath();
+    }
+
+    public long getLastModified() {
+        return f.lastModified();
+    }
+
+    public boolean delete() {
+        return f.delete();
+    }
+
+    public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
+        CharBuffer cb = fileManager.getCachedContent(this);
+        if (cb == null) {
+            InputStream in = new FileInputStream(f);
+            try {
+                ByteBuffer bb = fileManager.makeByteBuffer(in);
+                JavaFileObject prev = fileManager.log.useSource(this);
+                try {
+                    cb = fileManager.decode(bb, ignoreEncodingErrors);
+                } finally {
+                    fileManager.log.useSource(prev);
+                }
+                fileManager.recycleByteBuffer(bb);
+                if (!ignoreEncodingErrors) {
+                    fileManager.cache(this, cb);
+                }
+            } finally {
+                in.close();
+            }
+        }
+        return cb;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (!(other instanceof RegularFileObject)) {
+            return false;
+        }
+        RegularFileObject o = (RegularFileObject) other;
+        try {
+            return f.equals(o.f) || f.getCanonicalFile().equals(o.f.getCanonicalFile());
+        } catch (IOException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return f.hashCode();
+    }
+
+    public URI toUri() {
+        try {
+            String path = f.getAbsolutePath().replace(File.separatorChar, '/');
+            return new URI("file://" + path).normalize();
+        } catch (URISyntaxException ex) {
+            return f.toURI();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/SymbolArchive.java	Wed Jun 25 23:30:55 2008 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.tools.javac.file;
+
+import com.sun.tools.javac.util.List;
+import java.io.File;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import javax.tools.JavaFileObject;
+
+public class SymbolArchive extends ZipArchive {
+
+    final File origFile;
+    final String prefix;
+
+    public SymbolArchive(JavacFileManager fileManager, File orig, ZipFile zdir, String prefix) throws IOException {
+        super(fileManager, zdir);
+        this.origFile = orig;
+        this.prefix = prefix;
+    }
+
+    @Override
+    void addZipEntry(ZipEntry entry) {
+        String name = entry.getName();
+        if (!name.startsWith(prefix)) {
+            return;
+        }
+        name = name.substring(prefix.length());
+        int i = name.lastIndexOf('/');
+        String dirname = name.substring(0, i + 1);
+        String basename = name.substring(i + 1);
+        if (basename.length() == 0) {
+            return;
+        }
+        List<String> list = map.get(dirname);
+        if (list == null) {
+            list = List.nil();
+        }
+        list = list.prepend(basename);
+        map.put(dirname, list);
+    }
+
+    @Override
+    public JavaFileObject getFileObject(String subdirectory, String file) {
+        return super.getFileObject(prefix + subdirectory, file);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipArchive.java	Wed Jun 25 23:30:55 2008 -0700
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.tools.javac.file;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.file.JavacFileManager.Archive;
+import com.sun.tools.javac.util.List;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharsetDecoder;
+
+public class ZipArchive implements Archive {
+
+    public ZipArchive(JavacFileManager fm, ZipFile zdir) throws IOException {
+        this.fileManager = fm;
+        this.zdir = zdir;
+        this.map = new HashMap<String,List<String>>();
+        for (Enumeration<? extends ZipEntry> e = zdir.entries(); e.hasMoreElements(); ) {
+            ZipEntry entry;
+            try {
+                entry = e.nextElement();
+            } catch (InternalError ex) {
+                IOException io = new IOException();
+                io.initCause(ex); // convenience constructors added in Mustang :-(
+                throw io;
+            }
+            addZipEntry(entry);
+        }
+    }
+
+    void addZipEntry(ZipEntry entry) {
+        String name = entry.getName();
+        int i = name.lastIndexOf('/');
+        String dirname = name.substring(0, i+1);
+        String basename = name.substring(i+1);
+        if (basename.length() == 0)
+            return;
+        List<String> list = map.get(dirname);
+        if (list == null)
+            list = List.nil();
+        list = list.prepend(basename);
+        map.put(dirname, list);
+    }
+
+    public boolean contains(String name) {
+        int i = name.lastIndexOf('/');
+        String dirname = name.substring(0, i+1);
+        String basename = name.substring(i+1);
+        if (basename.length() == 0)
+            return false;
+        List<String> list = map.get(dirname);
+        return (list != null && list.contains(basename));
+    }
+
+    public List<String> getFiles(String subdirectory) {
+        return map.get(subdirectory);
+    }
+
+    public JavaFileObject getFileObject(String subdirectory, String file) {
+        ZipEntry ze = zdir.getEntry(subdirectory + file);
+        return new ZipFileObject(this, file, ze);
+    }
+
+    public Set<String> getSubdirectories() {
+        return map.keySet();
+    }
+
+    public void close() throws IOException {
+        zdir.close();
+    }
+
+    protected JavacFileManager fileManager;
+    protected final Map<String,List<String>> map;
+    protected final ZipFile zdir;
+
+    /**
+     * A subclass of JavaFileObject representing zip entries.
+     */
+    public static class ZipFileObject extends BaseFileObject {
+
+        private String name;
+        ZipArchive zarch;
+        ZipEntry entry;
+
+        public ZipFileObject(ZipArchive zarch, String name, ZipEntry entry) {
+            super(zarch.fileManager);
+            this.zarch = zarch;
+            this.name = name;
+            this.entry = entry;
+        }
+
+        public InputStream openInputStream() throws IOException {
+            return zarch.zdir.getInputStream(entry);
+        }
+
+        public OutputStream openOutputStream() throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
+            return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
+        }
+
+        public Writer openWriter() throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Deprecated
+        public String getName() {
+            return name;
+        }
+
+        public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
+            cn.getClass();
+            // null check
+            if (k == Kind.OTHER && getKind() != k) {
+                return false;
+            }
+            return name.equals(cn + k.extension);
+        }
+
+        @Deprecated
+        public String getPath() {
+            return zarch.zdir.getName() + "(" + entry + ")";
+        }
+
+        public long getLastModified() {
+            return entry.getTime();
+        }
+
+        public boolean delete() {
+            throw new UnsupportedOperationException();
+        }
+
+        public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
+            CharBuffer cb = fileManager.getCachedContent(this);
+            if (cb == null) {
+                InputStream in = zarch.zdir.getInputStream(entry);
+                try {
+                    ByteBuffer bb = fileManager.makeByteBuffer(in);
+                    JavaFileObject prev = fileManager.log.useSource(this);
+                    try {
+                        cb = fileManager.decode(bb, ignoreEncodingErrors);
+                    } finally {
+                        fileManager.log.useSource(prev);
+                    }
+                    fileManager.recycleByteBuffer(bb);
+                    if (!ignoreEncodingErrors) {
+                        fileManager.cache(this, cb);
+                    }
+                } finally {
+                    in.close();
+                }
+            }
+            return cb;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof ZipFileObject)) {
+                return false;
+            }
+            ZipFileObject o = (ZipFileObject) other;
+            return zarch.zdir.equals(o.zarch.zdir) || name.equals(o.name);
+        }
+
+        @Override
+        public int hashCode() {
+            return zarch.zdir.hashCode() + name.hashCode();
+        }
+
+        public String getZipName() {
+            return zarch.zdir.getName();
+        }
+
+        public String getZipEntryName() {
+            return entry.getName();
+        }
+
+        public URI toUri() {
+            String zipName = new File(getZipName()).toURI().normalize().getPath();
+            String entryName = getZipEntryName();
+            return URI.create("jar:" + zipName + "!" + entryName);
+        }
+
+        @Override
+        protected String inferBinaryName(Iterable<? extends File> path) {
+            String entryName = getZipEntryName();
+            if (zarch instanceof SymbolArchive) {
+                String prefix = ((SymbolArchive) zarch).prefix;
+                if (entryName.startsWith(prefix))
+                    entryName = entryName.substring(prefix.length());
+            }
+            return removeExtension(entryName).replace('/', '.');
+        }
+    }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java	Wed Jun 25 23:30:55 2008 -0700
@@ -81,11 +81,12 @@
     private File zipFile;
     private long zipFileLastModified = NOT_MODIFIED;
     private RandomAccessFile zipRandomFile;
-    private ZipFileIndexEntry[] entries;
+    private Entry[] entries;
 
     private boolean readFromIndex = false;
     private File zipIndexFile = null;
     private boolean triedToReadIndex = false;
+    final String symbolFilePrefix;
     private int symbolFilePrefixLength = 0;
     private boolean hasPopulatedData = false;
     private long lastReferenceTimeStamp = NOT_MODIFIED;
@@ -141,14 +142,14 @@
         }
     }
 
-    public static ZipFileIndex getZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean useCache, String cacheLocation, boolean writeIndex) throws IOException {
+    public static ZipFileIndex getZipFileIndex(File zipFile, String symbolFilePrefix, boolean useCache, String cacheLocation, boolean writeIndex) throws IOException {
         ZipFileIndex zi = null;
         lock.lock();
         try {
             zi = getExistingZipIndex(zipFile);
 
             if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) {
-                zi = new ZipFileIndex(zipFile, symbolFilePrefixLen, writeIndex,
+                zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex,
                         useCache, cacheLocation);
                 zipFileIndexCache.put(zipFile, zi);
             }
@@ -229,10 +230,12 @@
         }
     }
 
-    private ZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean writeIndex,
+    private ZipFileIndex(File zipFile, String symbolFilePrefix, boolean writeIndex,
             boolean useCache, String cacheLocation) throws IOException {
         this.zipFile = zipFile;
-        this.symbolFilePrefixLength = symbolFilePrefixLen;
+        this.symbolFilePrefix = symbolFilePrefix;
+        this.symbolFilePrefixLength = (symbolFilePrefix == null ? 0 :
+            symbolFilePrefix.getBytes("UTF-8").length);
         this.writeIndex = writeIndex;
         this.usePreindexedCache = useCache;
         this.preindexedCacheLocation = cacheLocation;
@@ -312,7 +315,7 @@
 
     private void cleanupState() {
         // Make sure there is a valid but empty index if the file doesn't exist
-        entries = ZipFileIndexEntry.EMPTY_ARRAY;
+        entries = Entry.EMPTY_ARRAY;
         directories = Collections.<String, DirectoryEntry>emptyMap();
         zipFileLastModified = NOT_MODIFIED;
         allDirs = Collections.<String>emptySet();
@@ -342,7 +345,7 @@
     /**
      * Returns the ZipFileIndexEntry for an absolute path, if there is one.
      */
-    public ZipFileIndexEntry getZipIndexEntry(String path) {
+    Entry getZipIndexEntry(String path) {
         if (File.separatorChar != '/') {
             path = path.replace('/', File.separatorChar);
         }
@@ -493,7 +496,7 @@
     public long getLastModified(String path) throws IOException {
         lock.lock();
         try {
-            ZipFileIndexEntry entry = getZipIndexEntry(path);
+            Entry entry = getZipIndexEntry(path);
             if (entry == null)
                 throw new FileNotFoundException();
             return entry.getLastModified();
@@ -506,7 +509,7 @@
     public int length(String path) throws IOException {
         lock.lock();
         try {
-            ZipFileIndexEntry entry = getZipIndexEntry(path);
+            Entry entry = getZipIndexEntry(path);
             if (entry == null)
                 throw new FileNotFoundException();
 
@@ -530,7 +533,7 @@
     public byte[] read(String path) throws IOException {
         lock.lock();
         try {
-            ZipFileIndexEntry entry = getZipIndexEntry(path);
+            Entry entry = getZipIndexEntry(path);
             if (entry == null)
                 throw new FileNotFoundException(MessageFormat.format("Path not found in ZIP: {0}", path));
             return read(entry);
@@ -540,7 +543,7 @@
         }
     }
 
-    public byte[] read(ZipFileIndexEntry entry) throws IOException {
+    byte[] read(Entry entry) throws IOException {
         lock.lock();
         try {
             openFile();
@@ -556,7 +559,7 @@
     public int read(String path, byte[] buffer) throws IOException {
         lock.lock();
         try {
-            ZipFileIndexEntry entry = getZipIndexEntry(path);
+            Entry entry = getZipIndexEntry(path);
             if (entry == null)
                 throw new FileNotFoundException();
             return read(entry, buffer);
@@ -566,7 +569,7 @@
         }
     }
 
-    public int read(ZipFileIndexEntry entry, byte[] buffer)
+    int read(Entry entry, byte[] buffer)
             throws IOException {
         lock.lock();
         try {
@@ -578,7 +581,7 @@
         }
     }
 
-    private byte[] readBytes(ZipFileIndexEntry entry) throws IOException {
+    private byte[] readBytes(Entry entry) throws IOException {
         byte[] header = getHeader(entry);
         int csize = entry.compressedSize;
         byte[] cbuf = new byte[csize];
@@ -600,7 +603,7 @@
     /**
      *
      */
-    private int readBytes(ZipFileIndexEntry entry, byte[] buffer) throws IOException {
+    private int readBytes(Entry entry, byte[] buffer) throws IOException {
         byte[] header = getHeader(entry);
 
         // entry is not compressed?
@@ -633,7 +636,7 @@
     // Zip utilities
     //----------------------------------------------------------------------------
 
-    private byte[] getHeader(ZipFileIndexEntry entry) throws IOException {
+    private byte[] getHeader(Entry entry) throws IOException {
         zipRandomFile.seek(entry.offset);
         byte[] header = new byte[30];
         zipRandomFile.readFully(header);
@@ -746,11 +749,11 @@
         private void buildIndex() throws IOException {
             int entryCount = get2ByteLittleEndian(zipDir, 0);
 
-            entries = new ZipFileIndexEntry[entryCount];
+            entries = new Entry[entryCount];
             // Add each of the files
             if (entryCount > 0) {
                 directories = new HashMap<String, DirectoryEntry>();
-                ArrayList<ZipFileIndexEntry> entryList = new ArrayList<ZipFileIndexEntry>();
+                ArrayList<Entry> entryList = new ArrayList<Entry>();
                 int pos = 2;
                 for (int i = 0; i < entryCount; i++) {
                     pos = readEntry(pos, entryList, directories);
@@ -759,19 +762,19 @@
                 // Add the accumulated dirs into the same list
                 Iterator i = directories.keySet().iterator();
                 while (i.hasNext()) {
-                    ZipFileIndexEntry zipFileIndexEntry = new ZipFileIndexEntry( (String) i.next());
+                    Entry zipFileIndexEntry = new Entry( (String) i.next());
                     zipFileIndexEntry.isDir = true;
                     entryList.add(zipFileIndexEntry);
                 }
 
-                entries = entryList.toArray(new ZipFileIndexEntry[entryList.size()]);
+                entries = entryList.toArray(new Entry[entryList.size()]);
                 Arrays.sort(entries);
             } else {
                 cleanupState();
             }
         }
 
-        private int readEntry(int pos, List<ZipFileIndexEntry> entryList,
+        private int readEntry(int pos, List<Entry> entryList,
                 Map<String, DirectoryEntry> directories) throws IOException {
             if (get4ByteLittleEndian(zipDir, pos) != 0x02014b50) {
                 throw new ZipException("cannot read zip file entry");
@@ -838,7 +841,7 @@
 
             // For each dir create also a file
             if (fileStart != fileEnd) {
-                ZipFileIndexEntry entry = new ZipFileIndexEntry(directory,
+                Entry entry = new Entry(directory,
                         new String(zipDir, fileStart, fileEnd - fileStart, "UTF-8"));
 
                 entry.setNativeTime(get4ByteLittleEndian(zipDir, pos + 12));
@@ -873,6 +876,7 @@
     /** ------------------------------------------------------------------------
      *  DirectoryEntry class
      * -------------------------------------------------------------------------*/
+
     static class DirectoryEntry {
         private boolean filesInited;
         private boolean directoriesInited;
@@ -885,9 +889,9 @@
 
         private com.sun.tools.javac.util.List<String> zipFileEntriesFiles = com.sun.tools.javac.util.List.<String>nil();
         private com.sun.tools.javac.util.List<String> zipFileEntriesDirectories = com.sun.tools.javac.util.List.<String>nil();
-        private com.sun.tools.javac.util.List<ZipFileIndexEntry>  zipFileEntries = com.sun.tools.javac.util.List.<ZipFileIndexEntry>nil();
+        private com.sun.tools.javac.util.List<Entry>  zipFileEntries = com.sun.tools.javac.util.List.<Entry>nil();
 
-        private List<ZipFileIndexEntry> entries = new ArrayList<ZipFileIndexEntry>();
+        private List<Entry> entries = new ArrayList<Entry>();
 
         private ZipFileIndex zipFileIndex;
 
@@ -916,7 +920,7 @@
 
             initEntries();
 
-            for (ZipFileIndexEntry e : entries) {
+            for (Entry e : entries) {
                 if (!e.isDir) {
                     zipFileEntriesFiles = zipFileEntriesFiles.append(e.name);
                 }
@@ -932,7 +936,7 @@
 
             initEntries();
 
-            for (ZipFileIndexEntry e : entries) {
+            for (Entry e : entries) {
                 if (e.isDir) {
                     zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name);
                 }
@@ -943,7 +947,7 @@
             return zipFileEntriesDirectories;
         }
 
-        private com.sun.tools.javac.util.List<ZipFileIndexEntry> getEntries() {
+        private com.sun.tools.javac.util.List<Entry> getEntries() {
             if (zipFileEntriesInited) {
                 return zipFileEntries;
             }
@@ -951,7 +955,7 @@
             initEntries();
 
             zipFileEntries = com.sun.tools.javac.util.List.nil();
-            for (ZipFileIndexEntry zfie : entries) {
+            for (Entry zfie : entries) {
                 zipFileEntries = zipFileEntries.append(zfie);
             }
 
@@ -960,9 +964,9 @@
             return zipFileEntries;
         }
 
-        private ZipFileIndexEntry getEntry(String rootName) {
+        private Entry getEntry(String rootName) {
             initEntries();
-            int index = Collections.binarySearch(entries, new ZipFileIndexEntry(dirName, rootName));
+            int index = Collections.binarySearch(entries, new Entry(dirName, rootName));
             if (index < 0) {
                 return null;
             }
@@ -977,9 +981,9 @@
 
             if (!zipFileIndex.readFromIndex) {
                 int from = -Arrays.binarySearch(zipFileIndex.entries,
-                        new ZipFileIndexEntry(dirName, ZipFileIndex.MIN_CHAR)) - 1;
+                        new Entry(dirName, ZipFileIndex.MIN_CHAR)) - 1;
                 int to = -Arrays.binarySearch(zipFileIndex.entries,
-                        new ZipFileIndexEntry(dirName, MAX_CHAR)) - 1;
+                        new Entry(dirName, MAX_CHAR)) - 1;
 
                 boolean emptyList = false;
 
@@ -1016,7 +1020,7 @@
                             // Read java time stamp of the file in the real Jar/Zip file
                             long eJavaTimestamp = raf.readLong();
 
-                            ZipFileIndexEntry rfie = new ZipFileIndexEntry(dirName, eName);
+                            Entry rfie = new Entry(dirName, eName);
                             rfie.isDir = eIsDir;
                             rfie.offset = eOffset;
                             rfie.size = eSize;
@@ -1041,7 +1045,7 @@
             entriesInited = true;
         }
 
-        List<ZipFileIndexEntry> getEntriesAsCollection() {
+        List<Entry> getEntriesAsCollection() {
             initEntries();
 
             return entries;
@@ -1173,8 +1177,8 @@
                 raf.seek(currFP);
 
                 // Now write each of the files in the DirectoryEntry
-                List<ZipFileIndexEntry> entries = de.getEntriesAsCollection();
-                for (ZipFileIndexEntry zfie : entries) {
+                List<Entry> entries = de.getEntriesAsCollection();
+                for (Entry zfie : entries) {
                     // Write the name bytes
                     byte [] zfieNameBytes = zfie.name.getBytes("UTF-8");
                     int zfieNameBytesLen = zfieNameBytes.length;
@@ -1245,4 +1249,94 @@
     public File getZipFile() {
         return zipFile;
     }
+
+
+    static class Entry implements Comparable<Entry> {
+        public static final Entry[] EMPTY_ARRAY = {};
+
+        // Directory related
+        String dir;
+        boolean isDir;
+
+        // File related
+        String name;
+
+        int offset;
+        int size;
+        int compressedSize;
+        long javatime;
+
+        private int nativetime;
+
+        public Entry(String path) {
+            int separator = path.lastIndexOf(File.separatorChar);
+            if (separator == -1) {
+                dir = "".intern();
+                name = path;
+            } else {
+                dir = path.substring(0, separator).intern();
+                name = path.substring(separator + 1);
+            }
+        }
+
+        public Entry(String directory, String name) {
+            this.dir = directory.intern();
+            this.name = name;
+        }
+
+        public String getName() {
+            if (dir == null || dir.length() == 0) {
+                return name;
+            }
+
+            StringBuilder sb = new StringBuilder();
+            sb.append(dir);
+            sb.append(File.separatorChar);
+            sb.append(name);
+            return sb.toString();
+        }
+
+        public String getFileName() {
+            return name;
+        }
+
+        public long getLastModified() {
+            if (javatime == 0) {
+                    javatime = dosToJavaTime(nativetime);
+            }
+            return javatime;
+        }
+
+        // From java.util.zip
+        private static long dosToJavaTime(int nativetime) {
+            // Bootstrap build problems prevent me from using the code directly
+            // Convert the raw/native time to a long for now
+            return (long)nativetime;
+        }
+
+        void setNativeTime(int natTime) {
+            nativetime = natTime;
+        }
+
+        public boolean isDirectory() {
+            return isDir;
+        }
+
+        public int compareTo(Entry other) {
+            String otherD = other.dir;
+            if (dir != otherD) {
+                int c = dir.compareTo(otherD);
+                if (c != 0)
+                    return c;
+            }
+            return name.compareTo(other.name);
+        }
+
+
+        public String toString() {
+            return isDir ? ("Dir:" + dir + " : " + name) :
+                (dir + ":" + name);
+        }
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java	Wed Jun 25 23:30:55 2008 -0700
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.tools.javac.file;
+
+import java.io.IOException;
+import java.util.Set;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.file.JavacFileManager.Archive;
+import com.sun.tools.javac.util.List;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharsetDecoder;
+
+public class ZipFileIndexArchive implements Archive {
+
+    private final ZipFileIndex zfIndex;
+    private JavacFileManager fileManager;
+
+    public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException {
+        super();
+        this.fileManager = fileManager;
+        this.zfIndex = zdir;
+    }
+
+    public boolean contains(String name) {
+        return zfIndex.contains(name);
+    }
+
+    public List<String> getFiles(String subdirectory) {
+        return zfIndex.getFiles((subdirectory.endsWith("/") || subdirectory.endsWith("\\")) ? subdirectory.substring(0, subdirectory.length() - 1) : subdirectory);
+    }
+
+    public JavaFileObject getFileObject(String subdirectory, String file) {
+        String fullZipFileName = subdirectory + file;
+        ZipFileIndex.Entry entry = zfIndex.getZipIndexEntry(fullZipFileName);
+        JavaFileObject ret = new ZipFileIndexFileObject(fileManager, zfIndex, entry, zfIndex.getZipFile().getPath());
+        return ret;
+    }
+
+    public Set<String> getSubdirectories() {
+        return zfIndex.getAllDirectories();
+    }
+
+    public void close() throws IOException {
+        zfIndex.close();
+    }
+
+    /**
+     * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.file.ZipFileIndex implementation.
+     */
+    public static class ZipFileIndexFileObject extends BaseFileObject {
+
+        /** The entry's name.
+         */
+        private String name;
+
+        /** The zipfile containing the entry.
+         */
+        ZipFileIndex zfIndex;
+
+        /** The underlying zip entry object.
+         */
+        ZipFileIndex.Entry entry;
+
+        /** The InputStream for this zip entry (file.)
+         */
+        InputStream inputStream = null;
+
+        /** The name of the zip file where this entry resides.
+         */
+        String zipName;
+
+
+        ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, String zipFileName) {
+            super(fileManager);
+            this.name = entry.getFileName();
+            this.zfIndex = zfIndex;
+            this.entry = entry;
+            this.zipName = zipFileName;
+        }
+
+        public InputStream openInputStream() throws IOException {
+
+            if (inputStream == null) {
+                inputStream = new ByteArrayInputStream(read());
+            }
+            return inputStream;
+        }
+
+        protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
+            return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
+        }
+
+        public OutputStream openOutputStream() throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        public Writer openWriter() throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        /** @deprecated see bug 6410637 */
+        @Deprecated
+        public String getName() {
+            return name;
+        }
+
+        public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
+            cn.getClass(); // null check
+            if (k == Kind.OTHER && getKind() != k)
+                return false;
+            return name.equals(cn + k.extension);
+        }
+
+        /** @deprecated see bug 6410637 */
+        @Deprecated
+        public String getPath() {
+            return zipName + "(" + entry.getName() + ")";
+        }
+
+        public long getLastModified() {
+            return entry.getLastModified();
+        }
+
+        public boolean delete() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof ZipFileIndexFileObject))
+                return false;
+            ZipFileIndexFileObject o = (ZipFileIndexFileObject) other;
+            return entry.equals(o.entry);
+        }
+
+        @Override
+        public int hashCode() {
+            return zipName.hashCode() + (name.hashCode() << 10);
+        }
+
+        public String getZipName() {
+            return zipName;
+        }
+
+        public String getZipEntryName() {
+            return entry.getName();
+        }
+
+        public URI toUri() {
+            String zipName = new File(getZipName()).toURI().normalize().getPath();
+            String entryName = getZipEntryName();
+            if (File.separatorChar != '/') {
+                entryName = entryName.replace(File.separatorChar, '/');
+            }
+            return URI.create("jar:" + zipName + "!" + entryName);
+        }
+
+        private byte[] read() throws IOException {
+            if (entry == null) {
+                entry = zfIndex.getZipIndexEntry(name);
+                if (entry == null)
+                  throw new FileNotFoundException();
+            }
+            return zfIndex.read(entry);
+        }
+
+        public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
+            CharBuffer cb = fileManager.getCachedContent(this);
+            if (cb == null) {
+                InputStream in = new ByteArrayInputStream(zfIndex.read(entry));
+                try {
+                    ByteBuffer bb = fileManager.makeByteBuffer(in);
+                    JavaFileObject prev = fileManager.log.useSource(this);
+                    try {
+                        cb = fileManager.decode(bb, ignoreEncodingErrors);
+                    } finally {
+                        fileManager.log.useSource(prev);
+                    }
+                    fileManager.recycleByteBuffer(bb); // save for next time
+                    if (!ignoreEncodingErrors)
+                        fileManager.cache(this, cb);
+                } finally {
+                    in.close();
+                }
+            }
+            return cb;
+        }
+
+        @Override
+        protected String inferBinaryName(Iterable<? extends File> path) {
+            String entryName = getZipEntryName();
+            if (zfIndex.symbolFilePrefix != null) {
+                String prefix = zfIndex.symbolFilePrefix;
+                if (entryName.startsWith(prefix))
+                    entryName = entryName.substring(prefix.length());
+            }
+            return removeExtension(entryName).replace(File.separatorChar, '.');
+        }
+    }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndexEntry.java	Fri Jun 20 16:36:18 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/*
- * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package com.sun.tools.javac.file;
-
-import java.io.File;
-
-public final class ZipFileIndexEntry implements Comparable<ZipFileIndexEntry> {
-    public static final ZipFileIndexEntry[] EMPTY_ARRAY = {};
-
-    // Directory related
-    String dir;
-    boolean isDir;
-
-    // File related
-    String name;
-
-    int offset;
-    int size;
-    int compressedSize;
-    long javatime;
-
-    private int nativetime;
-
-    public ZipFileIndexEntry(String path) {
-        int separator = path.lastIndexOf(File.separatorChar);
-        if (separator == -1) {
-            dir = "".intern();
-            name = path;
-        } else {
-            dir = path.substring(0, separator).intern();
-            name = path.substring(separator + 1);
-        }
-    }
-
-    public ZipFileIndexEntry(String directory, String name) {
-        this.dir = directory.intern();
-        this.name = name;
-    }
-
-    public String getName() {
-        if (dir == null || dir.length() == 0) {
-            return name;
-        }
-
-        StringBuilder sb = new StringBuilder();
-        sb.append(dir);
-        sb.append(File.separatorChar);
-        sb.append(name);
-        return sb.toString();
-    }
-
-    public String getFileName() {
-        return name;
-    }
-
-    public long getLastModified() {
-        if (javatime == 0) {
-                javatime = dosToJavaTime(nativetime);
-        }
-        return javatime;
-    }
-
-    // From java.util.zip
-    private static long dosToJavaTime(int nativetime) {
-        // Bootstrap build problems prevent me from using the code directly
-        // Convert the raw/native time to a long for now
-        return (long)nativetime;
-    }
-
-    void setNativeTime(int natTime) {
-        nativetime = natTime;
-    }
-
-    public boolean isDirectory() {
-        return isDir;
-    }
-
-    public int compareTo(ZipFileIndexEntry other) {
-        String otherD = other.dir;
-        if (dir != otherD) {
-            int c = dir.compareTo(otherD);
-            if (c != 0)
-                return c;
-        }
-        return name.compareTo(other.name);
-    }
-
-
-    public String toString() {
-        return isDir ? ("Dir:" + dir + " : " + name) :
-            (dir + ":" + name);
-    }
-}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Jun 25 23:30:55 2008 -0700
@@ -1056,7 +1056,7 @@
     void readClassAttr(ClassSymbol c, Name attrName, int attrLen) {
         if (attrName == names.SourceFile) {
             Name n = readName(nextChar());
-            c.sourcefile = new SourceFileObject(n);
+            c.sourcefile = new SourceFileObject(n, c.flatname);
         } else if (attrName == names.InnerClasses) {
             readInnerClasses(c);
         } else if (allowGenerics && attrName == names.Signature) {
@@ -2221,9 +2221,12 @@
         /** The file's name.
          */
         private Name name;
+        private Name flatname;
 
-        public SourceFileObject(Name name) {
+        public SourceFileObject(Name name, Name flatname) {
+            super(null); // no file manager; never referenced for this file object
             this.name = name;
+            this.flatname = flatname;
         }
 
         public InputStream openInputStream() {
@@ -2285,5 +2288,9 @@
             throw new UnsupportedOperationException();
         }
 
+        @Override
+        protected String inferBinaryName(Iterable<? extends File> path) {
+            return flatname.toString();
+        }
     }
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Wed Jun 25 23:30:55 2008 -0700
@@ -34,7 +34,6 @@
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaFileObject;
 
-import com.sun.tools.javac.code.Source;
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -86,10 +85,6 @@
      */
     public boolean emitWarnings;
 
-    /** Enforce mandatory warnings.
-     */
-    private boolean enforceMandatoryWarnings;
-
     /** Print stack trace on errors?
      */
     public boolean dumpOnError;
@@ -138,9 +133,6 @@
         DiagnosticListener<? super JavaFileObject> diagListener =
             context.get(DiagnosticListener.class);
         this.diagListener = diagListener;
-
-        Source source = Source.instance(context);
-        this.enforceMandatoryWarnings = source.enforceMandatoryWarnings();
     }
     // where
         private int getIntOption(Options options, String optionName, int defaultValue) {
@@ -473,10 +465,7 @@
      *  @param args   Fields of the warning message.
      */
     public void mandatoryWarning(DiagnosticPosition pos, String key, Object ... args) {
-        if (enforceMandatoryWarnings)
-            report(diags.mandatoryWarning(source, pos, key, args));
-        else
-            report(diags.warning(source, pos, key, args));
+        report(diags.mandatoryWarning(source, pos, key, args));
     }
 
     /** Report a warning that cannot be suppressed.
@@ -514,34 +503,43 @@
     }
 
     /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
+     *  @param file   The file to which the note applies.
+     *  @param key    The key for the localized notification message.
+     *  @param args   Fields of the notification message.
+     */
+    public void note(JavaFileObject file, String key, Object ... args) {
+        report(diags.note(wrap(file), null, key, args));
+    }
+
+    /** Provide a non-fatal notification, unless suppressed by the -nowarn option.
      *  @param key    The key for the localized notification message.
      *  @param args   Fields of the notification message.
      */
     public void mandatoryNote(final JavaFileObject file, String key, Object ... args) {
-        JCDiagnostic.DiagnosticSource wrapper = null;
-        if (file != null) {
-            wrapper = new JCDiagnostic.DiagnosticSource() {
-                    public JavaFileObject getFile() {
-                        return file;
-                    }
-                    public CharSequence getName() {
-                        return JavacFileManager.getJavacBaseFileName(getFile());
-                    }
-                    public int getLineNumber(int pos) {
-                        return Log.this.getLineNumber(pos);
-                    }
-                    public int getColumnNumber(int pos) {
-                        return Log.this.getColumnNumber(pos);
-                    }
-                    public Map<JCTree, Integer> getEndPosTable() {
-                        return (endPosTables == null ? null : endPosTables.get(file));
-                    }
-                };
+        report(diags.mandatoryNote(wrap(file), key, args));
+    }
+
+    private JCDiagnostic.DiagnosticSource wrap(final JavaFileObject file) {
+        if (file == null) {
+            return null;
         }
-        if (enforceMandatoryWarnings)
-            report(diags.mandatoryNote(wrapper, key, args));
-        else
-            report(diags.note(wrapper, null, key, args));
+        return new JCDiagnostic.DiagnosticSource() {
+            public JavaFileObject getFile() {
+                return file;
+            }
+            public CharSequence getName() {
+                return JavacFileManager.getJavacBaseFileName(getFile());
+            }
+            public int getLineNumber(int pos) {
+                return Log.this.getLineNumber(pos);
+            }
+            public int getColumnNumber(int pos) {
+                return Log.this.getColumnNumber(pos);
+            }
+            public Map<JCTree, Integer> getEndPosTable() {
+                return (endPosTables == null ? null : endPosTables.get(file));
+            }
+        };
     }
 
     private DiagnosticPosition wrap(int pos) {
--- a/langtools/src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java	Wed Jun 25 23:30:55 2008 -0700
@@ -101,13 +101,17 @@
      *                individual instances should be given, or whether an aggregate
      *                message should be generated at the end of the compilation.
      *                Typically set via  -Xlint:option.
+     * @param enforceMandatory
+     *                True if mandatory warnings and notes are being enforced.
      * @param prefix  A common prefix for the set of message keys for
      *                the messages that may be generated.
      */
-    public MandatoryWarningHandler(Log log, boolean verbose, String prefix) {
+    public MandatoryWarningHandler(Log log, boolean verbose,
+                                   boolean enforceMandatory, String prefix) {
         this.log = log;
         this.verbose = verbose;
         this.prefix = prefix;
+        this.enforceMandatory = enforceMandatory;
     }
 
     /**
@@ -122,7 +126,7 @@
 
             if (log.nwarnings < log.MaxWarnings) {
                 // generate message and remember the source file
-                log.mandatoryWarning(pos, msg, args);
+                logMandatoryWarning(pos, msg, args);
                 sourcesWithReportedWarnings.add(currentSource);
             } else if (deferredDiagnosticKind == null) {
                 // set up deferred message
@@ -163,12 +167,12 @@
     public void reportDeferredDiagnostic() {
         if (deferredDiagnosticKind != null) {
             if (deferredDiagnosticArg == null)
-                log.mandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix));
+                logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix));
             else
-                log.mandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg);
+                logMandatoryNote(deferredDiagnosticSource, deferredDiagnosticKind.getKey(prefix), deferredDiagnosticArg);
 
             if (!verbose)
-                log.mandatoryNote(deferredDiagnosticSource, prefix + ".recompile");
+                logMandatoryNote(deferredDiagnosticSource, prefix + ".recompile");
         }
     }
 
@@ -224,4 +228,32 @@
      * deferredDiagnosticKind is updated.
      */
     private Object deferredDiagnosticArg;
+
+    /**
+     * True if mandatory warnings and notes are being enforced.
+     */
+    private final boolean enforceMandatory;
+
+    /**
+     * Reports a mandatory warning to the log.  If mandatory warnings
+     * are not being enforced, treat this as an ordinary warning.
+     */
+    private void logMandatoryWarning(DiagnosticPosition pos, String msg,
+                                     Object... args) {
+        if (enforceMandatory)
+            log.mandatoryWarning(pos, msg, args);
+        else
+            log.warning(pos, msg, args);
+    }
+
+    /**
+     * Reports a mandatory note to the log.  If mandatory notes are
+     * not being enforced, treat this as an ordinary note.
+     */
+    private void logMandatoryNote(JavaFileObject file, String msg, Object... args) {
+        if (enforceMandatory)
+            log.mandatoryNote(file, msg, args);
+        else
+            log.note(file, msg, args);
+    }
 }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocClassReader.java	Wed Jun 25 23:30:55 2008 -0700
@@ -27,7 +27,9 @@
 
 import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.file.ZipArchive.ZipFileObject;
 import com.sun.tools.javac.file.Old199;
+import com.sun.tools.javac.file.ZipFileIndexArchive;
 import com.sun.tools.javac.jvm.ClassReader;
 import com.sun.tools.javac.util.Context;
 
@@ -82,16 +84,16 @@
     protected void extraFileActions(PackageSymbol pack, JavaFileObject fo) {
         CharSequence fileName = Old199.getName(fo);
         if (docenv != null && fileName.equals("package.html")) {
-            if (fo instanceof JavacFileManager.ZipFileObject) {
-                JavacFileManager.ZipFileObject zfo = (JavacFileManager.ZipFileObject) fo;
+            if (fo instanceof ZipFileObject) {
+                ZipFileObject zfo = (ZipFileObject) fo;
                 String zipName = zfo.getZipName();
                 String entryName = zfo.getZipEntryName();
                 int lastSep = entryName.lastIndexOf("/");
                 String classPathName = entryName.substring(0, lastSep + 1);
                 docenv.getPackageDoc(pack).setDocPath(zipName, classPathName);
             }
-            else if (fo instanceof JavacFileManager.ZipFileIndexFileObject) {
-                JavacFileManager.ZipFileIndexFileObject zfo = (JavacFileManager.ZipFileIndexFileObject) fo;
+            else if (fo instanceof ZipFileIndexArchive.ZipFileIndexFileObject) {
+                ZipFileIndexArchive.ZipFileIndexFileObject zfo = (ZipFileIndexArchive.ZipFileIndexFileObject) fo;
                 String zipName = zfo.getZipName();
                 String entryName = zfo.getZipEntryName();
                 if (File.separatorChar != '/') {
--- a/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javap/JavapFileManager.java	Wed Jun 25 23:30:55 2008 -0700
@@ -25,16 +25,13 @@
 
 package com.sun.tools.javap;
 
-import java.io.File;
 import java.io.PrintWriter;
 import java.nio.charset.Charset;
-import javax.tools.Diagnostic;
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.JCDiagnostic;
 
 /**
  *  javap's implementation of JavaFileManager.
@@ -52,29 +49,8 @@
     static JavapFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log, Options options) {
         Context javac_context = new Context();
 
-        if (dl != null) {
-            // Workaround bug 6625520: javac handles missing entries on classpath badly
-            // Ignore spurious errors for missing files
-            DiagnosticListener<JavaFileObject> wrapper = new DiagnosticListener<JavaFileObject>() {
-                public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
-                    if (diagnostic instanceof JCDiagnostic) {
-                        JCDiagnostic jcd = (JCDiagnostic) diagnostic;
-                        if (jcd.getCode().equals("compiler.err.error.reading.file")) {
-                            Object[] args = jcd.getArgs();
-                            if (args.length > 0 && args[0] != null && args[0].toString().length() > 0) {
-                                File f = new File(args[0].toString());
-                                if (!f.exists())
-                                    return;
-                            }
-                        }
-
-                    }
-                    dl.report(diagnostic);
-                }
-            };
-            javac_context.put(DiagnosticListener.class, wrapper);
-        }
-
+        if (dl != null)
+            javac_context.put(DiagnosticListener.class, dl);
         javac_context.put(com.sun.tools.javac.util.Log.outKey, log);
 
         return new JavapFileManager(javac_context, null);
--- a/langtools/test/tools/javac/T6358024.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/test/tools/javac/T6358024.java	Wed Jun 25 23:30:55 2008 -0700
@@ -36,6 +36,7 @@
 import com.sun.source.util.*;
 import com.sun.tools.javac.api.*;
 import com.sun.tools.javac.file.*;
+import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.main.*;
 import com.sun.tools.javac.util.*;
 
--- a/langtools/test/tools/javac/T6358166.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/test/tools/javac/T6358166.java	Wed Jun 25 23:30:55 2008 -0700
@@ -33,6 +33,7 @@
 import javax.lang.model.element.*;
 import javax.tools.*;
 import com.sun.tools.javac.file.*;
+import com.sun.tools.javac.file.JavacFileManager; // disambiguate
 import com.sun.tools.javac.main.JavaCompiler;
 import com.sun.tools.javac.main.*;
 import com.sun.tools.javac.util.*;
--- a/langtools/test/tools/javac/T6358168.java	Fri Jun 20 16:36:18 2008 -0700
+++ b/langtools/test/tools/javac/T6358168.java	Wed Jun 25 23:30:55 2008 -0700
@@ -34,6 +34,7 @@
 import javax.lang.model.element.*;
 import javax.tools.*;
 import com.sun.tools.javac.file.*;
+import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.main.JavaCompiler;
 import com.sun.tools.javac.main.*;
 import com.sun.tools.javac.util.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T6625520.java	Wed Jun 25 23:30:55 2008 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.tools.*;
+import com.sun.tools.javac.file.*;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.util.*;
+
+/*
+ * @test
+ * @bug 6625520
+ * @summary javac handles missing entries on classpath badly
+ */
+public class T6625520 {
+    public static void main(String[] args) throws Exception {
+        new T6625520().run();
+    }
+
+    void run() throws Exception {
+        Context c = new Context();
+        DiagnosticCollector<JavaFileObject> dc =
+            new DiagnosticCollector<JavaFileObject>();
+        c.put(DiagnosticListener.class, dc);
+        StandardJavaFileManager fm = new JavacFileManager(c, false, null);
+        fm.setLocation(StandardLocation.CLASS_PATH,
+                       Arrays.asList(new File("DOES_NOT_EXIST.jar")));
+        FileObject fo = fm.getFileForInput(StandardLocation.CLASS_PATH,
+                                           "p", "C.java");
+        System.err.println(fo + "\n" + dc.getDiagnostics());
+        if (dc.getDiagnostics().size() > 0)
+            throw new Exception("unexpected diagnostics found");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6294779/T6294779a.java	Wed Jun 25 23:30:55 2008 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     6294779
+ * @summary Problem with interface inheritance and covariant return types
+ * @author  Maurizio Cimadamore
+ * @compile T6294779a.java
+ */
+
+public class T6294779a {
+
+    interface A {
+        A m();
+    }
+
+    interface B extends A {
+        B m();
+    }
+
+    interface C extends A {
+        C m();
+    }
+
+    interface D extends B, C {
+        D m();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6294779/T6294779b.java	Wed Jun 25 23:30:55 2008 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     6294779
+ * @summary Problem with interface inheritance and covariant return types
+ * @author  Maurizio Cimadamore
+ * @compile T6294779b.java
+ */
+
+import java.util.*;
+
+class T6294779b {
+
+    interface I1<E> {
+        List<E> m();
+    }
+
+    interface I2<E> {
+        Queue<E> m();
+    }
+
+    interface I3<E> {
+        LinkedList<E> m();
+    }
+
+    interface I4<E> extends I1<E>, I2<E>, I3<E> {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/6294779/T6294779c.java	Wed Jun 25 23:30:55 2008 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     6294779
+ * @summary Problem with interface inheritance and covariant return types
+ * @author  Maurizio Cimadamore
+ * @compile/fail T6294779c.java
+ */
+
+public class T6294779c<X> {
+
+    interface A {}
+
+    interface B {}
+
+    interface C {}
+
+    interface I1 {
+        T6294779c<? extends A> get();
+    }
+
+    interface I2 {
+        T6294779c<? extends B> get();
+    }
+
+    interface I3 {
+        T6294779c<? extends C> get();
+    }
+
+    interface I4 extends I1, I2, I3 {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/sourceOption/SourceOption.java	Wed Jun 25 23:30:55 2008 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug     6507179
+ * @summary Ensure that "-source" option isn't ignored.
+ * @author  Scott Seligman
+ */
+
+import com.sun.javadoc.*;
+
+public class SourceOption extends Doclet {
+
+    public static void main(String[] args) {
+        if (com.sun.tools.javadoc.Main.execute(
+                "javadoc",
+                "SourceOption",
+                new String[] {"-source", "1.3", "p"}) != 0)
+            throw new Error("Javadoc encountered warnings or errors.");
+    }
+
+    public static boolean start(RootDoc root) {
+        root.classes();         // force parser into action
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/sourceOption/p/A.java	Wed Jun 25 23:30:55 2008 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package p;
+
+public class A {
+    boolean assert;     // illegal since 1.4
+    boolean enum;       // illegal since 5
+}