You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by to...@apache.org on 2008/01/08 11:55:41 UTC

svn commit: r609928 [2/5] - in /harmony/enhanced/classlib/branches/java6: ./ make/ modules/awt/src/main/java/unix/org/apache/harmony/awt/gl/linux/ modules/awt/src/main/java/windows/org/apache/harmony/awt/gl/windows/ modules/awt/src/main/native/gl/share...

Modified: harmony/enhanced/classlib/branches/java6/modules/imageio/src/main/java/javax/imageio/ImageReader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/imageio/src/main/java/javax/imageio/ImageReader.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/imageio/src/main/java/javax/imageio/ImageReader.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/imageio/src/main/java/javax/imageio/ImageReader.java Tue Jan  8 02:55:24 2008
@@ -14,56 +14,57 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-/**
- * @author Rustem V. Rafikov
- * @version $Revision: 1.3 $
- */
 package javax.imageio;
 
-import javax.imageio.spi.ImageReaderSpi;
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.metadata.IIOMetadata;
-import javax.imageio.event.IIOReadWarningListener;
-import javax.imageio.event.IIOReadProgressListener;
-import javax.imageio.event.IIOReadUpdateListener;
-
-import org.apache.harmony.luni.util.NotImplementedException;
-
-import java.util.Locale;
-import java.util.List;
-import java.util.Iterator;
-import java.util.Set;
-import java.io.IOException;
+import java.awt.Rectangle;
 import java.awt.image.BufferedImage;
 import java.awt.image.Raster;
 import java.awt.image.RenderedImage;
-import java.awt.*;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+import javax.imageio.event.IIOReadProgressListener;
+import javax.imageio.event.IIOReadUpdateListener;
+import javax.imageio.event.IIOReadWarningListener;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.ImageInputStream;
+
+import org.apache.harmony.x.imageio.internal.nls.Messages;
 
 public abstract class ImageReader {
 
-    protected ImageReaderSpi originatingProvider;
+    protected ImageReaderSpi                originatingProvider;
 
-    protected Object input;
+    protected Object                        input;
 
-    protected boolean seekForwardOnly;
+    protected boolean                       seekForwardOnly;
 
-    protected boolean ignoreMetadata;
+    protected boolean                       ignoreMetadata;
 
-    protected int minIndex;
+    protected int                           minIndex;
 
-    protected Locale[] availableLocales;
+    protected Locale[]                      availableLocales;
 
-    protected Locale locale;
+    protected Locale                        locale;
 
-    protected List<IIOReadWarningListener> warningListeners;
+    protected List<IIOReadWarningListener>  warningListeners;
 
-    protected List<Locale> warningLocales;
+    protected List<Locale>                  warningLocales;
 
     protected List<IIOReadProgressListener> progressListeners;
 
-    protected List<IIOReadUpdateListener> updateListeners;
+    protected List<IIOReadUpdateListener>   updateListeners;
 
-    protected ImageReader(ImageReaderSpi originatingProvider) {
+    private boolean                         isAborted;
+
+    protected ImageReader(final ImageReaderSpi originatingProvider) {
         this.originatingProvider = originatingProvider;
     }
 
@@ -75,10 +76,13 @@
         return originatingProvider;
     }
 
-    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
+    public void setInput(final Object input, final boolean seekForwardOnly,
+                    final boolean ignoreMetadata) {
         if (input != null) {
             if (!isSupported(input) && !(input instanceof ImageInputStream)) {
-                throw new IllegalArgumentException("input " + input + " is not supported");
+                throw new IllegalArgumentException(Messages.getString(
+                    "imageio.2", //$NON-NLS-1$
+                    input));
             }
         }
         this.minIndex = 0;
@@ -87,10 +91,11 @@
         this.input = input;
     }
 
-    private boolean isSupported(Object input) {
+    private boolean isSupported(final Object input) {
         ImageReaderSpi spi = getOriginatingProvider();
         if (null != spi) {
-            Class[] outTypes = spi.getInputTypes();
+            Class<?>[] outTypes = spi.getInputTypes();
+
             for (Class<?> element : outTypes) {
                 if (element.isInstance(input)) {
                     return true;
@@ -100,11 +105,11 @@
         return false;
     }
 
-    public void setInput(Object input, boolean seekForwardOnly) {
+    public void setInput(final Object input, final boolean seekForwardOnly) {
         setInput(input, seekForwardOnly, false);
     }
 
-    public void setInput(Object input) {
+    public void setInput(final Object input) {
         setInput(input, false, false);
     }
 
@@ -128,316 +133,448 @@
         return availableLocales;
     }
 
-    public void setLocale(Locale locale) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void setLocale(final Locale locale) {
+        if (locale != null) {
+            final Locale[] locales = getAvailableLocales();
+
+            if ((locales == null) || !arrayContains(locales, locale)) {
+                throw new IllegalArgumentException(Messages.getString(
+                    "imageio.3", //$NON-NLS-1$
+                    "Locale " + locale)); //$NON-NLS-1$
+            }
+        }
+
+        this.locale = locale;
     }
 
     public Locale getLocale() {
         return locale;
     }
 
-    public abstract int getNumImages(boolean allowSearch) throws IOException;
+    public abstract int getNumImages(final boolean allowSearch)
+                    throws IOException;
 
-    public abstract int getWidth(int imageIndex) throws IOException;
+    public abstract int getWidth(final int imageIndex) throws IOException;
 
-    public abstract int getHeight(int imageIndex) throws IOException;
+    public abstract int getHeight(final int imageIndex) throws IOException;
 
-    public boolean isRandomAccessEasy(int imageIndex) throws IOException {
-        return false; //def
+    public boolean isRandomAccessEasy(final int imageIndex) throws IOException {
+        return false;
     }
 
-    public float getAspectRatio(int imageIndex) throws IOException {
+    public float getAspectRatio(final int imageIndex) throws IOException {
         return (float) getWidth(imageIndex) / getHeight(imageIndex);
     }
 
-    public ImageTypeSpecifier getRawImageType(int imageIndex) throws IOException, NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public ImageTypeSpecifier getRawImageType(final int imageIndex)
+                    throws IOException {
+        return getImageTypes(imageIndex).next();
     }
 
-    public abstract Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException;
+    public abstract Iterator<ImageTypeSpecifier> getImageTypes(
+                    final int imageIndex) throws IOException;
 
-    public ImageReadParam getDefaultReadParam() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public ImageReadParam getDefaultReadParam() {
+        return new ImageReadParam();
     }
 
     public abstract IIOMetadata getStreamMetadata() throws IOException;
 
-    public IIOMetadata getStreamMetadata(String formatName, Set<String> nodeNames)
-            throws IOException, NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public IIOMetadata getStreamMetadata(final String formatName,
+                    final Set<String> nodeNames) throws IOException {
+        iaeIfNull("formatName", formatName); //$NON-NLS-1$
+        iaeIfNull("nodeNames", nodeNames); //$NON-NLS-1$
+
+        final IIOMetadata data = getStreamMetadata();
+        return isSupportedFormat(formatName, data) ? data : null;
     }
 
-    public abstract IIOMetadata getImageMetadata(int imageIndex) throws IOException;
+    public abstract IIOMetadata getImageMetadata(final int imageIndex)
+                    throws IOException;
 
-    public IIOMetadata getImageMetadata(int imageIndex, String formatName,
-                                        Set<String> nodeNames) throws IOException, NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public IIOMetadata getImageMetadata(final int imageIndex,
+                    final String formatName, final Set<String> nodeNames)
+                    throws IOException {
+        iaeIfNull("formatName", formatName); //$NON-NLS-1$
+        iaeIfNull("nodeNames", nodeNames); //$NON-NLS-1$
+
+        final IIOMetadata data = getImageMetadata(imageIndex);
+        return isSupportedFormat(formatName, data) ? data : null;
     }
 
-    public BufferedImage read(int imageIndex) throws IOException {
+    public BufferedImage read(final int imageIndex) throws IOException {
         return read(imageIndex, null);
     }
 
-    public abstract BufferedImage read(int imageIndex, ImageReadParam param) throws IOException;
+    public abstract BufferedImage read(final int imageIndex,
+                    final ImageReadParam param) throws IOException;
+
+    public IIOImage readAll(final int imageIndex, final ImageReadParam param)
+                    throws IOException {
+        List<BufferedImage> th = null;
+        final BufferedImage img = read(imageIndex, param);
+        final int num = getNumThumbnails(imageIndex);
+
+        if (num > 0) {
+            th = new ArrayList<BufferedImage>(num);
+
+            for (int i = 0; i < num; i++) {
+                th.add(readThumbnail(imageIndex, i));
+            }
+        }
 
-    public IIOImage readAll(int imageIndex, ImageReadParam param) throws IOException, NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+        return new IIOImage(img, th, getImageMetadata(imageIndex));
     }
 
-    public Iterator<IIOImage> readAll(Iterator<? extends ImageReadParam> params) throws IOException, NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public Iterator<IIOImage> readAll(
+                    final Iterator<? extends ImageReadParam> params)
+                    throws IOException {
+        final int index = getMinIndex();
+        final List<IIOImage> list = new LinkedList<IIOImage>();
+
+        processSequenceStarted(index);
+
+        while (params.hasNext()) {
+            try {
+                list.add(readAll(index, params.next()));
+            } catch (final ClassCastException ex) {
+                throw new IllegalArgumentException(ex);
+            }
+        }
+
+        processSequenceComplete();
+        return list.iterator();
     }
 
     public boolean canReadRaster() {
-        return false; //def
+        return false; // def
     }
 
-    public Raster readRaster(int imageIndex, ImageReadParam param) throws IOException {
-        throw new UnsupportedOperationException("Unsupported");
+    public Raster readRaster(final int imageIndex, final ImageReadParam param)
+                    throws IOException {
+        throw new UnsupportedOperationException(Messages.getString("imageio.7", //$NON-NLS-1$
+            "readRaster()")); //$NON-NLS-1$
     }
 
-    public boolean isImageTiled(int imageIndex) throws IOException {
-        return false; //def
+    public boolean isImageTiled(final int imageIndex) throws IOException {
+        return false; // def
     }
 
-    public int getTileWidth(int imageIndex) throws IOException {
-        return getWidth(imageIndex); //def
+    public int getTileWidth(final int imageIndex) throws IOException {
+        return getWidth(imageIndex); // def
     }
 
-    public int getTileHeight(int imageIndex) throws IOException {
-        return getHeight(imageIndex); //def
+    public int getTileHeight(final int imageIndex) throws IOException {
+        return getHeight(imageIndex); // def
     }
 
-    public int getTileGridXOffset(int imageIndex) throws IOException {
-        return 0; //def
+    public int getTileGridXOffset(final int imageIndex) throws IOException {
+        return 0; // def
     }
 
-    public int getTileGridYOffset(int imageIndex) throws IOException {
-        return 0; //def
+    public int getTileGridYOffset(final int imageIndex) throws IOException {
+        return 0; // def
     }
 
-    public BufferedImage readTile(int imageIndex, int tileX, int tileY) throws IOException, NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public BufferedImage readTile(final int imageIndex, final int tileX,
+                    final int tileY) throws IOException {
+        if ((tileX != 0) || (tileY != 0)) {
+            throw new IllegalArgumentException(Messages.getString("imageio.5", //$NON-NLS-1$
+                "0", "tileX & tileY")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return read(imageIndex);
     }
 
-    public Raster readTileRaster(int imageIndex, int tileX, int tileY) throws IOException, NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public Raster readTileRaster(final int imageIndex, final int tileX,
+                    final int tileY) throws IOException {
+        if (canReadRaster()) {
+            if ((tileX != 0) || (tileY != 0)) {
+                throw new IllegalArgumentException(Messages.getString(
+                    "imageio.5", //$NON-NLS-1$
+                    "0", "tileX & tileY")); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+            return readRaster(imageIndex, null);
+        }
+
+        throw new UnsupportedOperationException(Messages.getString("imageio.7", //$NON-NLS-1$
+            "readTileRaster()")); //$NON-NLS-1$
     }
 
-    public RenderedImage readAsRenderedImage(int imageIndex, ImageReadParam param) throws IOException {
+    public RenderedImage readAsRenderedImage(final int imageIndex,
+                    final ImageReadParam param) throws IOException {
         return read(imageIndex, param);
     }
 
     public boolean readerSupportsThumbnails() {
-        return false; //def
+        return false; // def
     }
 
-    public boolean hasThumbnails(int imageIndex) throws IOException {
-        return getNumThumbnails(imageIndex) > 0; //def
+    public boolean hasThumbnails(final int imageIndex) throws IOException {
+        return getNumThumbnails(imageIndex) > 0; // def
     }
 
-    public int getNumThumbnails(int imageIndex) throws IOException {
-        return 0; //def
+    public int getNumThumbnails(final int imageIndex) throws IOException {
+        return 0; // def
     }
 
-    public int getThumbnailWidth(int imageIndex, int thumbnailIndex) throws IOException {
-        return readThumbnail(imageIndex, thumbnailIndex).getWidth();  //def
+    public int getThumbnailWidth(final int imageIndex, final int thumbnailIndex)
+                    throws IOException {
+        return readThumbnail(imageIndex, thumbnailIndex).getWidth(); // def
     }
 
-    public int getThumbnailHeight(int imageIndex, int thumbnailIndex) throws IOException {
-        return readThumbnail(imageIndex, thumbnailIndex).getHeight();  //def
+    public int getThumbnailHeight(final int imageIndex, final int thumbnailIndex)
+                    throws IOException {
+        return readThumbnail(imageIndex, thumbnailIndex).getHeight(); // def
     }
 
-    public BufferedImage readThumbnail(int imageIndex, int thumbnailIndex) throws IOException {
-        throw new UnsupportedOperationException("Unsupported"); //def
+    public BufferedImage readThumbnail(final int imageIndex,
+                    final int thumbnailIndex) throws IOException {
+        throw new UnsupportedOperationException(Messages.getString("imageio.7", //$NON-NLS-1$
+            "readThumbnail()")); //$NON-NLS-1$
     }
 
-    public void abort() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void abort() {
+        isAborted = true;
     }
 
-    protected boolean abortRequested() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected boolean abortRequested() {
+        return isAborted;
     }
 
-    protected void clearAbortRequest() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void clearAbortRequest() {
+        isAborted = false;
     }
 
-    public void addIIOReadWarningListener(IIOReadWarningListener listener) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void addIIOReadWarningListener(final IIOReadWarningListener listener) {
+        if (listener != null) {
+            warningListeners = addToList(warningListeners, listener);
+            warningLocales = addToList(warningLocales, getLocale());
+        }
     }
 
-    public void removeIIOReadWarningListener(IIOReadWarningListener listener) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void removeIIOReadWarningListener(
+                    final IIOReadWarningListener listener) {
+        final int ind;
+
+        if ((warningListeners != null) && (listener != null)
+            && ((ind = warningListeners.indexOf(listener)) != -1)) {
+            warningListeners.remove(ind);
+            warningLocales.remove(ind);
+        }
     }
 
-    public void removeAllIIOReadWarningListeners() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void removeAllIIOReadWarningListeners() {
+        warningListeners = null;
+        warningLocales = null;
     }
 
-    public void addIIOReadProgressListener(IIOReadProgressListener listener) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void addIIOReadProgressListener(
+                    final IIOReadProgressListener listener) {
+        if (listener != null) {
+            progressListeners = addToList(progressListeners, listener);
+        }
     }
 
-    public void removeIIOReadProgressListener(IIOReadProgressListener listener) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void removeIIOReadProgressListener(
+                    final IIOReadProgressListener listener) {
+        if ((progressListeners != null) && (listener != null)) {
+            progressListeners.remove(listener);
+        }
     }
 
-    public void removeAllIIOReadProgressListeners() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void removeAllIIOReadProgressListeners() {
+        progressListeners = null;
     }
 
-    public void addIIOReadUpdateListener(IIOReadUpdateListener listener) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void addIIOReadUpdateListener(final IIOReadUpdateListener listener) {
+        if (listener != null) {
+            updateListeners = addToList(updateListeners, listener);
+        }
     }
 
-    public void removeIIOReadUpdateListener(IIOReadUpdateListener listener) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void removeIIOReadUpdateListener(final IIOReadUpdateListener listener) {
+        if ((updateListeners != null) && (listener != null)) {
+            updateListeners.remove(listener);
+        }
     }
 
-    public void removeAllIIOReadUpdateListeners() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    public void removeAllIIOReadUpdateListeners() {
+        updateListeners = null;
     }
 
-    protected void processSequenceStarted(int minIndex) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processSequenceStarted(final int minIndex) {
+        if (progressListeners != null) {
+            for (final IIOReadProgressListener listener : progressListeners) {
+                listener.sequenceStarted(this, minIndex);
+            }
+        }
     }
 
-    protected void processSequenceComplete() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processSequenceComplete() {
+        if (progressListeners != null) {
+            for (final IIOReadProgressListener listener : progressListeners) {
+                listener.sequenceComplete(this);
+            }
+        }
     }
 
-    protected void processImageStarted(int imageIndex) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processImageStarted(final int imageIndex) {
+        if (progressListeners != null) {
+            for (final IIOReadProgressListener listener : progressListeners) {
+                listener.imageStarted(this, imageIndex);
+            }
+        }
     }
 
-    protected void processImageProgress(float percentageDone) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processImageProgress(final float percentageDone) {
+        if (progressListeners != null) {
+            for (final IIOReadProgressListener listener : progressListeners) {
+                listener.imageProgress(this, percentageDone);
+            }
+        }
     }
 
-    protected void processImageComplete() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processImageComplete() {
+        if (progressListeners != null) {
+            for (final IIOReadProgressListener listener : progressListeners) {
+                listener.imageComplete(this);
+            }
+        }
     }
 
-    protected void processThumbnailStarted(int imageIndex, int thumbnailIndex) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processThumbnailStarted(final int imageIndex,
+                    final int thumbnailIndex) {
+        if (progressListeners != null) {
+            for (final IIOReadProgressListener listener : progressListeners) {
+                listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
+            }
+        }
     }
 
-    protected void processThumbnailProgress(float percentageDone) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processThumbnailProgress(final float percentageDone) {
+        if (progressListeners != null) {
+            for (final IIOReadProgressListener listener : progressListeners) {
+                listener.thumbnailProgress(this, percentageDone);
+            }
+        }
     }
 
-    protected void processThumbnailComplete() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processThumbnailComplete() {
+        if (progressListeners != null) {
+            for (final IIOReadProgressListener listener : progressListeners) {
+                listener.thumbnailComplete(this);
+            }
+        }
     }
 
-    protected void processReadAborted() throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processReadAborted() {
+        if (progressListeners != null) {
+            for (final IIOReadProgressListener listener : progressListeners) {
+                listener.readAborted(this);
+            }
+        }
     }
 
-    protected void processPassStarted(BufferedImage theImage,
-                                  int pass,
-                                  int minPass,
-                                  int maxPass,
-                                  int minX,
-                                  int minY,
-                                  int periodX,
-                                  int periodY,
-                                  int[] bands) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processPassStarted(final BufferedImage theImage,
+                    final int pass, final int minPass, final int maxPass,
+                    final int minX, final int minY, final int periodX,
+                    final int periodY, final int[] bands) {
+        if (updateListeners != null) {
+            for (final IIOReadUpdateListener listener : updateListeners) {
+                listener.passStarted(this, theImage, pass, minPass, maxPass,
+                    minX, minY, periodX, periodY, bands);
+            }
+        }
     }
 
-    protected void processImageUpdate(BufferedImage theImage,
-                                  int minX,
-                                  int minY,
-                                  int width,
-                                  int height,
-                                  int periodX,
-                                  int periodY,
-                                  int[] bands) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processImageUpdate(final BufferedImage theImage,
+                    final int minX, final int minY, final int width,
+                    final int height, final int periodX, final int periodY,
+                    final int[] bands) {
+        if (updateListeners != null) {
+            for (final IIOReadUpdateListener listener : updateListeners) {
+                listener.imageUpdate(this, theImage, minX, minY, width, height,
+                    periodX, periodY, bands);
+            }
+        }
     }
 
-    protected void processPassComplete(BufferedImage theImage) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processPassComplete(final BufferedImage theImage) {
+        if (updateListeners != null) {
+            for (IIOReadUpdateListener listener : updateListeners) {
+                listener.passComplete(this, theImage);
+            }
+        }
     }
 
-    protected void processThumbnailPassStarted(BufferedImage theThumbnail,
-                                           int pass,
-                                           int minPass,
-                                           int maxPass,
-                                           int minX,
-                                           int minY,
-                                           int periodX,
-                                           int periodY,
-                                           int[] bands) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processThumbnailPassStarted(
+                    final BufferedImage theThumbnail, final int pass,
+                    final int minPass, final int maxPass, final int minX,
+                    final int minY, final int periodX, final int periodY,
+                    final int[] bands) {
+        if (updateListeners != null) {
+            for (final IIOReadUpdateListener listener : updateListeners) {
+                listener.thumbnailPassStarted(this, theThumbnail, pass,
+                    minPass, maxPass, minX, minY, periodX, periodY, bands);
+            }
+        }
     }
 
-    protected void processThumbnailUpdate(BufferedImage theThumbnail,
-                                      int minX,
-                                      int minY,
-                                      int width,
-                                      int height,
-                                      int periodX,
-                                      int periodY,
-                                       int[] bands) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processThumbnailUpdate(final BufferedImage theThumbnail,
+                    final int minX, final int minY, final int width,
+                    final int height, final int periodX, final int periodY,
+                    final int[] bands) {
+        if (updateListeners != null) {
+            for (final IIOReadUpdateListener listener : updateListeners) {
+                listener.thumbnailUpdate(this, theThumbnail, minX, minY, width,
+                    height, periodX, periodY, bands);
+            }
+        }
     }
 
-    protected void processThumbnailPassComplete(BufferedImage theThumbnail) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processThumbnailPassComplete(final BufferedImage theThumbnail) {
+        if (updateListeners != null) {
+            for (final IIOReadUpdateListener listener : updateListeners) {
+                listener.thumbnailPassComplete(this, theThumbnail);
+            }
+        }
     }
 
-    protected void processWarningOccurred(String warning) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processWarningOccurred(final String warning) {
+        if (warningListeners != null) {
+            iaeIfNull("warning", warning); //$NON-NLS-1$
+            for (final IIOReadWarningListener listener : warningListeners) {
+                listener.warningOccurred(this, warning);
+            }
+        }
     }
 
-    protected void processWarningOccurred(String baseName, String keyword) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected void processWarningOccurred(final String baseName,
+                    final String keyword) {
+        if (warningListeners != null) {
+            int i = 0;
+
+            iaeIfNull("keyword", keyword); //$NON-NLS-1$
+            iaeIfNull("baseName", baseName); //$NON-NLS-1$
+
+            for (final IIOReadWarningListener listener : warningListeners) {
+                try {
+                    final Locale locale = warningLocales.get(i);
+                    final ResourceBundle bundle = (locale != null)
+                        ? ResourceBundle.getBundle(baseName, locale)
+                        : ResourceBundle.getBundle(baseName);
+                    listener.warningOccurred(this, bundle.getString(keyword));
+                } catch (final RuntimeException ex) {
+                    throw new IllegalArgumentException(ex.getMessage());
+                }
+
+                i++;
+            }
+        }
     }
 
     public void reset() {
-        // def
         setInput(null, false);
         setLocale(null);
         removeAllIIOReadUpdateListeners();
@@ -450,33 +587,185 @@
         // do nothing by def
     }
 
-    protected static Rectangle getSourceRegion(ImageReadParam param, int srcWidth, int srcHeight) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
-    }
-
-    protected static void computeRegions(ImageReadParam param,
-                                     int srcWidth,
-                                     int srcHeight,
-                                     BufferedImage image,
-                                     Rectangle srcRegion,
-                                     Rectangle destRegion) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
-    }
-
-    protected static void checkReadParamBandSettings(ImageReadParam param,
-                                                 int numSrcBands,
-                                                 int numDstBands) throws NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
-    }
-
-    protected static BufferedImage getDestination(ImageReadParam param, Iterator<ImageTypeSpecifier> imageTypes,
-                                              int width,
-                                              int height)
-                                       throws IIOException, NotImplementedException {
-        // TODO: implement
-        throw new NotImplementedException();
+    protected static Rectangle getSourceRegion(final ImageReadParam param,
+                    final int srcWidth, final int srcHeight) {
+        final Rectangle r = new Rectangle(0, 0, srcWidth, srcHeight);
+
+        if (param != null) {
+            final int x;
+            final int y;
+            final Rectangle sr = param.getSourceRegion();
+
+            if (sr != null) {
+                r.setBounds(r.intersection(sr));
+            }
+
+            x = param.getSubsamplingXOffset();
+            y = param.getSubsamplingYOffset();
+            r.x += x;
+            r.y += y;
+            r.width -= x;
+            r.height -= y;
+        }
+
+        return r;
+    }
+
+    protected static void computeRegions(final ImageReadParam param,
+                    final int srcWidth, final int srcHeight,
+                    final BufferedImage image, final Rectangle srcRegion,
+                    final Rectangle destRegion) {
+        int xCols = 1;
+        int yCols = 1;
+
+        iaeIfNull("srcRegion", srcRegion); //$NON-NLS-1$
+        iaeIfNull("destRegion", destRegion); //$NON-NLS-1$
+        iaeIfEmpty("srcRegion", srcRegion.isEmpty()); //$NON-NLS-1$
+        iaeIfEmpty("destRegion", destRegion.isEmpty()); //$NON-NLS-1$
+
+        srcRegion.setBounds(getSourceRegion(param, srcWidth, srcHeight));
+
+        if (param != null) {
+            destRegion.setLocation(param.getDestinationOffset());
+            xCols = param.getSourceXSubsampling();
+            yCols = param.getSourceYSubsampling();
+        }
+
+        if (destRegion.x < 0) {
+            final int shift = -destRegion.x * xCols;
+            srcRegion.x += shift;
+            srcRegion.width -= shift;
+            destRegion.x = 0;
+        }
+
+        if (destRegion.y < 0) {
+            final int shift = -destRegion.y * yCols;
+            srcRegion.y += shift;
+            srcRegion.height -= shift;
+            destRegion.y = 0;
+        }
+
+        destRegion.width = srcRegion.width / xCols;
+        destRegion.height = srcRegion.height / yCols;
+
+        if (image != null) {
+            destRegion.setBounds(destRegion.intersection(new Rectangle(0, 0,
+                            image.getWidth(), image.getHeight())));
+        }
+    }
+
+    protected static void checkReadParamBandSettings(
+                    final ImageReadParam param, final int numSrcBands,
+                    final int numDstBands) {
+        final int[] src = (param != null) ? param.getSourceBands() : null;
+        final int[] dst = (param != null) ? param.getDestinationBands() : null;
+        final int srcLen = (src != null) ? src.length : numSrcBands;
+        final int dstLen = (dst != null) ? dst.length : numDstBands;
+
+        if (srcLen != dstLen) {
+            throw new IllegalArgumentException("srcLen != dstLen"); //$NON-NLS-1$
+        }
+
+        if (src != null) {
+            for (int i = 0; i < srcLen; i++) {
+                if (src[i] >= numSrcBands) {
+                    throw new IllegalArgumentException("src[" + i //$NON-NLS-1$
+                        + "] >= numSrcBands"); //$NON-NLS-1$
+                }
+            }
+        }
+
+        if (dst != null) {
+            for (int i = 0; i < dstLen; i++) {
+                if (dst[i] >= numDstBands) {
+                    throw new IllegalArgumentException("dst[" + i //$NON-NLS-1$
+                        + "] >= numDstBands"); //$NON-NLS-1$
+                }
+            }
+        }
+    }
+
+    protected static BufferedImage getDestination(final ImageReadParam param,
+                    final Iterator<ImageTypeSpecifier> imageTypes,
+                    final int width, final int height) throws IIOException {
+        iaeIfNull("imageTypes", imageTypes); //$NON-NLS-1$
+        iaeIfEmpty("imageTypes", !imageTypes.hasNext()); //$NON-NLS-1$
+
+        if ((long) (width * height) > (long) Integer.MAX_VALUE) {
+            throw new IllegalArgumentException(
+                            "width * height > Integer.MAX_VALUE!"); //$NON-NLS-1$
+        }
+
+        final Rectangle dst;
+        ImageTypeSpecifier its = null;
+
+        if (param != null) {
+            final BufferedImage img = param.getDestination();
+
+            if (img != null) {
+                return img;
+            }
+
+            its = param.getDestinationType();
+        }
+
+        try {
+            isValid: if (its != null) {
+                while (imageTypes.hasNext()) {
+                    if (its.equals((ImageTypeSpecifier) imageTypes.next())) {
+                        break isValid;
+                    }
+                }
+                throw new IIOException(Messages.getString("imageio.3", its)); //$NON-NLS-1$
+            } else {
+                its = imageTypes.next();
+            }
+        } catch (final ClassCastException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+
+        dst = new Rectangle(0, 0, 0, 0);
+        computeRegions(param, width, height, null, new Rectangle(0, 0, 0, 0),
+            dst);
+        return its.createBufferedImage(dst.width, dst.height);
+    }
+
+    private static <T> List<T> addToList(List<T> list, final T value) {
+        if (list == null) {
+            list = new LinkedList<T>();
+        }
+
+        list.add(value);
+        return list;
+    }
+
+    private static void iaeIfNull(final String name, final Object value) {
+        if (value == null) {
+            throw new IllegalArgumentException(Messages.getString("imageio.2", //$NON-NLS-1$
+                name));
+        }
+    }
+
+    private static void iaeIfEmpty(final String name, final boolean isEmpty) {
+        if (isEmpty) {
+            throw new IllegalArgumentException(Messages.getString("imageio.6", //$NON-NLS-1$
+                name));
+        }
+    }
+
+    private static <T> boolean arrayContains(final T[] array, final Object value) {
+        for (T t : array) {
+            if ((t == value) || ((t != null) && t.equals(value))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean isSupportedFormat(final String formatName,
+                    final IIOMetadata data) {
+        final String[] names;
+        return ((data != null) && ((names = data.getMetadataFormatNames()) != null))
+            ? arrayContains(names, formatName) : false;
     }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/imageio/src/main/java/org/apache/harmony/x/imageio/internal/nls/messages.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/imageio/src/main/java/org/apache/harmony/x/imageio/internal/nls/messages.properties?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/imageio/src/main/java/org/apache/harmony/x/imageio/internal/nls/messages.properties (original)
+++ harmony/enhanced/classlib/branches/java6/modules/imageio/src/main/java/org/apache/harmony/x/imageio/internal/nls/messages.properties Tue Jan  8 02:55:24 2008
@@ -15,4 +15,10 @@
 # 
 
 # messages for EN locale
-imageio.1=Wrong bitDepth-numBands composition
\ No newline at end of file
+imageio.1=Wrong bitDepth-numBands composition
+imageio.2="{0}" is null
+imageio.3="{0}" is not valid
+imageio.4={0} {1} {2}
+imageio.5="{0}" value expected for "{1}"
+imageio.6="{0}" is empty
+imageio.7="{0}" is not supported

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/javax/naming/InitialContext.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/javax/naming/InitialContext.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/javax/naming/InitialContext.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/main/java/javax/naming/InitialContext.java Tue Jan  8 02:55:24 2008
@@ -72,7 +72,7 @@
  * to construct a classname suffix in the following form:<br>
  * 
  * <pre>
- *     &lt;package_prefix&gt; . &lt;scheme&gt; . &lt;scheme&gt;URLContextFactory
+ *            &lt;package_prefix&gt; . &lt;scheme&gt; . &lt;scheme&gt;URLContextFactory
  * </pre>
  * 
  * Several variants of the classname are constructed using each element of the
@@ -171,6 +171,16 @@
     }
 
     /**
+     * Contains loaded properties for each classloader
+     */
+    private static Hashtable<ClassLoader, Hashtable<Object, Object>> propsCache = new Hashtable<ClassLoader, Hashtable<Object, Object>>();
+    
+    /**
+     * Contians properties load from java.home/lib/jndi.properties
+     */
+    private static Hashtable<Object, Object> libProperties = null;
+
+    /**
      * Constructs an <code>InitialContext</code> instance without using any
      * environment properties. This constructor is effectively the same as using
      * constructor <code>InitialContext((Hashtable)null)</code>.
@@ -248,11 +258,26 @@
         EnvironmentReader.readSystemProperties(myProps);
 
         // 4.1 Read application/applet resource files
-        EnvironmentReader.readApplicationResourceFiles(myProps);
-
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if (propsCache.containsKey(cl)) {
+            EnvironmentReader.mergeEnvironment(propsCache.get(cl), myProps,
+                    true);
+        } else {
+            Hashtable<Object, Object> appProps = new Hashtable<Object, Object>();
+            EnvironmentReader.readApplicationResourceFiles(appProps);
+            propsCache.put(cl, appProps);
+            EnvironmentReader.mergeEnvironment(appProps, myProps, true);
+        }
+        
         // 4.2 Read "java.home"/lib/jndi.properties
-        EnvironmentReader.readLibraryResourceFile(myProps);
-
+        if (libProperties == null) {
+            libProperties = new Hashtable<Object, Object>();
+            EnvironmentReader.readLibraryResourceFile(libProperties);
+        }
+        
+        EnvironmentReader.mergeEnvironment(libProperties, myProps, true);
+        
+        
         // 5. No need to read service provider resource files
 
         // if JNDI standard property "java.naming.factory.initial" has a
@@ -262,6 +287,7 @@
             // defaultInitCtx
             getDefaultInitCtx();
         }
+
     }
 
     /**
@@ -407,7 +433,7 @@
                 if (null == ctx) {
                     ctx = getDefaultInitCtx();
                 }
-                contextCache.put(scheme, ctx);               
+                contextCache.put(scheme, ctx);
             }
             return ctx;
         }
@@ -550,7 +576,7 @@
     }
 
     public Object addToEnvironment(String propName, Object propVal)
-            throws NamingException {        
+            throws NamingException {
         synchronized (contextCache) {
             myProps.put(propName, propVal);
             contextCache.clear();
@@ -579,7 +605,6 @@
     public String getNameInNamespace() throws NamingException {
         return getDefaultInitCtx().getNameInNamespace();
     }
-    
-    
-    private HashMap<String, Context> contextCache = new HashMap<String, Context>();   
+
+    private HashMap<String, Context> contextCache = new HashMap<String, Context>();
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/tests/javax/naming/InitialContextAppTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/tests/javax/naming/InitialContextAppTest.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/tests/javax/naming/InitialContextAppTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/jndi/src/test/java/org/apache/harmony/jndi/tests/javax/naming/InitialContextAppTest.java Tue Jan  8 02:55:24 2008
@@ -16,36 +16,155 @@
  */
 package org.apache.harmony.jndi.tests.javax.naming;
 
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.PrintStream;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.Hashtable;
 
+import javax.naming.InitialContext;
 import javax.naming.NamingException;
 
 import junit.framework.TestCase;
 import org.apache.harmony.jndi.tests.javax.naming.util.Log;
 
 public class InitialContextAppTest extends TestCase {
-	private static final Log log = new Log(InitialContextAppTest.class);
+    private static final Log log = new Log(InitialContextAppTest.class);
+
+    public void testConstructor_App() throws NamingException, IOException {
+        // Comment this test case out because this test case
+        // needs complex configuration about jndi properties.
+
+        // log.setMethod("testConstructor_App");
+        // InitialContext context = new InitialContext();
+        // Hashtable props = context.getEnvironment();
+        // // printHashtable(props);
+        // Hashtable expected = TestInitialContextLib.readAllProps(null);
+        // assertEquals(expected, props);
+    }
+
+    /**
+     * regression: Harmony-4942
+     * 
+     */
+    public void testConstructor() throws Exception {
+        final File file1 = new File("src/test/resources/test1");
+        if (!file1.exists()) {
+            file1.mkdir();
+        }
+
+        URL url = file1.toURL();
+        URLClassLoader cltest1 = new URLClassLoader(new URL[] { url }, Thread
+                .currentThread().getContextClassLoader());
+        Thread test1 = new Thread(new Runnable() {
+
+            public void run() {
+                try {
+                    File propsFile = new File(file1.toString()
+                            + "/jndi.properties");
+
+                    FileOutputStream fos = new FileOutputStream(propsFile);
+
+                    PrintStream ps = new PrintStream(fos);
+                    ps
+                            .println("java.naming.factory.initial=org.apache.harmony.jndi.tests.javax.naming.spi.mock.MockContextFactory");
+                    ps.println("java.naming.provider.url=http://test1");
+                    ps.close();
+
+                    InitialContext context = new InitialContext();
+                    Hashtable<?, ?> env = context.getEnvironment();
+                    assertEquals(
+                            "org.apache.harmony.jndi.tests.javax.naming.spi.mock.MockContextFactory",
+                            env.get("java.naming.factory.initial"));
+                    assertEquals("http://test1", env
+                            .get("java.naming.provider.url"));
+
+                    propsFile.delete();
+
+                    // create new properties file with different values
+                    fos = new FileOutputStream(propsFile);
+                    ps = new PrintStream(fos);
+                    ps
+                            .println("java.naming.factory.initial=not.exist.ContextFactory");
+                    ps.println("java.naming.provider.url=http://test1.new");
+                    ps.close();
+
+                    context = new InitialContext();
+                    env = context.getEnvironment();
+                    assertEquals(
+                            "org.apache.harmony.jndi.tests.javax.naming.spi.mock.MockContextFactory",
+                            env.get("java.naming.factory.initial"));
+                    assertEquals("http://test1", env
+                            .get("java.naming.provider.url"));
+
+                    propsFile.delete();
+                } catch (Exception e) {
+                    fail(e.getMessage());
+                }
+            }
+
+        });
+        // use different classloader
+        test1.setContextClassLoader(cltest1);
+
+        test1.start();
+
+        final File file2 = new File("src/test/resources/test2");
+        if (!file2.exists()) {
+            file2.mkdir();
+        }
+        url = file2.toURL();
+        URLClassLoader cltest2 = new URLClassLoader(new URL[] { url }, Thread
+                .currentThread().getContextClassLoader());
+
+        Thread test2 = new Thread(new Runnable() {
+
+            public void run() {
+                try {
+                    File propsFile = new File(file2.toString()
+                            + "/jndi.properties");
+                    FileOutputStream fos = new FileOutputStream(propsFile);
+                    PrintStream ps = new PrintStream(fos);
+                    ps
+                            .println("java.naming.factory.initial=org.apache.harmony.jndi.tests.javax.naming.spi.mock.MockContextFactory");
+                    ps.println("java.naming.provider.url=http://test2");
+                    ps.close();
+
+                    InitialContext context = new InitialContext();
+                    Hashtable<?, ?> env = context.getEnvironment();
+                    assertEquals(
+                            "org.apache.harmony.jndi.tests.javax.naming.spi.mock.MockContextFactory",
+                            env.get("java.naming.factory.initial"));
+                    assertEquals("http://test2", env
+                            .get("java.naming.provider.url"));
+
+                    propsFile.delete();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+
+        });
+
+        // use different classloader
+        test2.setContextClassLoader(cltest2);
+        test2.start();
+
+        Thread.sleep(1000);
+        file1.deleteOnExit();
+        file2.deleteOnExit();
+    }
 
-	public void testConstructor_App() throws NamingException, IOException {
-		//Comment this test case out because this test case 
-		//needs complex configuration about jndi properties.
-		
-//		log.setMethod("testConstructor_App");
-//		InitialContext context = new InitialContext();
-//		Hashtable props = context.getEnvironment();
-//		// printHashtable(props);
-//		Hashtable expected = TestInitialContextLib.readAllProps(null);
-//		assertEquals(expected, props);
-	}
-
-	void printHashtable(Hashtable<?, ?> env) {
-		// TO DO: Need to remove
-		Enumeration<?> keys = env.keys();
-		while (keys.hasMoreElements()) {
-			Object key = keys.nextElement();
-			log.log(key + "=" + env.get(key));
-		}
-	}
+    void printHashtable(Hashtable<?, ?> env) {
+        // TO DO: Need to remove
+        Enumeration<?> keys = env.keys();
+        while (keys.hasMoreElements()) {
+            Object key = keys.nextElement();
+            log.log(key + "=" + env.get(key));
+        }
+    }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/DataInputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/DataInputStream.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/DataInputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/DataInputStream.java Tue Jan  8 02:55:24 2008
@@ -413,10 +413,13 @@
 
 
     String decodeUTF(int utfSize) throws IOException {
+        return decodeUTF(utfSize, this);
+    }
 
+    private static String decodeUTF(int utfSize, DataInput in) throws IOException {
         byte[] buf = new byte[utfSize];
         char[] out = new char[utfSize];
-        readFully(buf, 0, utfSize);
+        in.readFully(buf, 0, utfSize);
 
         return Util.convertUTF8WithBuf(buf, out, 0, utfSize);
     }
@@ -434,7 +437,7 @@
      * @see DataOutput#writeUTF(java.lang.String)
      */
     public static final String readUTF(DataInput in) throws IOException {
-        return in.readUTF();
+        return decodeUTF(in.readUnsignedShort(), in);
     }
 
     /**

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/FileDescriptor.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/FileDescriptor.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/FileDescriptor.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/FileDescriptor.java Tue Jan  8 02:55:24 2008
@@ -93,5 +93,7 @@
      * @return <code>true</code> if this FileDescriptor is valid,
      *         <code>false</code> otherwise
      */
-    public native boolean valid();
+    public boolean valid() {
+        return descriptor != -1;
+    }
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectOutputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectOutputStream.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectOutputStream.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectOutputStream.java Tue Jan  8 02:55:24 2008
@@ -38,6 +38,11 @@
         ObjectStreamConstants {
 
     /*
+     * Mask to zero SC_BLOC_DATA bit.
+     */
+    private static final byte NOT_SC_BLOCK_DATA = (byte) (SC_BLOCK_DATA ^ 0xFF);
+
+    /*
      * How many nested levels to writeObject. We may not need this.
      */
     private int nestedLevels;
@@ -311,7 +316,7 @@
      *             If an error occurs attempting to drain the data
      */
     protected void drain() throws IOException {
-        if (primitiveTypes == null) {
+        if (primitiveTypes == null || primitiveTypesBuffer == null) {
             return;
         }
 
@@ -1531,12 +1536,13 @@
         boolean externalizable = false;
         externalizable = ObjectStreamClass.isExternalizable(classDesc
                 .forClass());
-        if (protocolVersion != PROTOCOL_VERSION_1) {
-            // Change for 1.2. Objects can be saved in old format
-            // (PROTOCOL_VERSION_1) or in the 1.2 format (PROTOCOL_VERSION_2).
-            // Nested "if" check to optimize checking. Second check is more
-            // expensive.
-            if (externalizable) {
+
+        if (externalizable) {
+            if (protocolVersion == PROTOCOL_VERSION_1) {
+                flags &= NOT_SC_BLOCK_DATA;
+            } else {
+                // Change for 1.2. Objects can be saved in old format
+                // (PROTOCOL_VERSION_1) or in the 1.2 format (PROTOCOL_VERSION_2).
                 flags |= SC_BLOCK_DATA;
             }
         }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamClass.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamClass.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamClass.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/io/ObjectStreamClass.java Tue Jan  8 02:55:24 2008
@@ -267,6 +267,7 @@
         boolean externalizable = isExternalizable(cl);
         if (externalizable) {
             flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
+            flags |= ObjectStreamConstants.SC_BLOCK_DATA; // use protocol version 2 by default
         } else if (serializable) {
             flags |= ObjectStreamConstants.SC_SERIALIZABLE;
         }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/SocketImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/SocketImpl.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/SocketImpl.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/SocketImpl.java Tue Jan  8 02:55:24 2008
@@ -20,7 +20,6 @@
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InterruptedIOException;
 import java.io.OutputStream;
 
 import org.apache.harmony.luni.platform.INetworkSystem;
@@ -33,9 +32,9 @@
  * Streaming sockets are wrapped by two classes, ServerSocket and Socket at the
  * server and client end of a connection respectively. At the server there are
  * two types of sockets engaged in communication, the <code>ServerSocket</code>
- * on a well known port (hereafter refered to as the listener) used to establish
- * a connection and the resulting <code>Socket</code> (hereafter refered to as
- * host).
+ * on a well known port (hereafter referred to as the listener) used to
+ * establish a connection and the resulting <code>Socket</code> (hereafter
+ * referred to as host).
  * 
  * Some of the <code>SocketImpl</code> instance variable values must be
  * interpreted in the context of the wrapper. See the getter methods for these
@@ -82,7 +81,7 @@
      * Answer the number of bytes that may be read from this socket without
      * blocking. This call does not block.
      * 
-     * @return int the number of bytes that may be read without blocking
+     * @return the number of bytes that may be read without blocking
      * @exception SocketException
      *                if an error occurs while peeking
      */
@@ -155,10 +154,10 @@
     }
 
     /**
-     * Answer the socket's address. Refering to the class comment: Listener: The
-     * local machines IP address to which this socket is bound. Host: The client
-     * machine, to which this socket is connected. Client: The host machine, to
-     * which this socket is connected.
+     * Answer the socket's address. Referring to the class comment: Listener:
+     * The local machines IP address to which this socket is bound. Host: The
+     * client machine, to which this socket is connected. Client: The host
+     * machine, to which this socket is connected.
      * 
      * @return InetAddress the socket address
      */
@@ -180,7 +179,7 @@
      * demand will go to the IP stack to get the bound value. See the class
      * comment for the context of the local port.
      * 
-     * @return int the socket localport
+     * @return the socket localport
      */
 
     protected int getLocalPort() {
@@ -211,7 +210,7 @@
      * Answer the socket's remote port. This value is not meaningful when the
      * socketImpl is wrapped by a ServerSocket.
      * 
-     * @return int the remote port the socket is connected to
+     * @return the remote port the socket is connected to
      */
     protected int getPort() {
         return port;
@@ -246,7 +245,7 @@
      * Answers a string containing a concise, human-readable description of the
      * socket.
      * 
-     * @return String the description
+     * @return the description
      */
     @SuppressWarnings("nls")
     @Override
@@ -266,7 +265,7 @@
      *            the offset into the buffer
      * @param count
      *            the number of bytes to write
-     * @return int the actual number of bytes written
+     * @return the actual number of bytes written
      * @exception IOException
      *                thrown if an error occurs while writing
      */
@@ -281,11 +280,11 @@
     /**
      * Shutdown the input portion of the socket.
      * 
-     * The default implementation always throws an {@link IOException}
-     * to indicate that the subclass should have overridden this
-     * method.
+     * The default implementation always throws an {@link IOException} to
+     * indicate that the subclass should have overridden this method.
      * 
-     * @throws IOException Always.  Designed to be subclassed.
+     * @throws IOException
+     *             Always. Designed to be subclassed.
      */
     protected void shutdownInput() throws IOException {
         // KA025=Method has not been implemented
@@ -295,11 +294,11 @@
     /**
      * Shutdown the output portion of the socket.
      * 
-     * The default implementation always throws an {@link IOException}
-     * to indicate that the subclass should have overridden this
-     * method.
+     * The default implementation always throws an {@link IOException} to
+     * indicate that the subclass should have overridden this method.
      * 
-     * @throws IOException Always.  Designed to be subclassed.
+     * @throws IOException
+     *             Always. Designed to be subclassed.
      */
     protected void shutdownOutput() throws IOException {
         // KA025=Method has not been implemented

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/URLClassLoader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/URLClassLoader.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/URLClassLoader.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/URLClassLoader.java Tue Jan  8 02:55:24 2008
@@ -1173,7 +1173,7 @@
     }
 
     Class<?> findClassImpl(String className) {
-        Class loadedClass = findLoadedClass(className);
+        Class<?> loadedClass = findLoadedClass(className);
         if (null != loadedClass) {
             return loadedClass;
         }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/URLConnection.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/URLConnection.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/URLConnection.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/net/URLConnection.java Tue Jan  8 02:55:24 2008
@@ -23,6 +23,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Collections;
+import java.util.Date;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
@@ -31,7 +32,6 @@
 import org.apache.harmony.luni.internal.net.www.MimeTable;
 import org.apache.harmony.luni.util.Msg;
 import org.apache.harmony.luni.util.PriviAction;
-import org.apache.harmony.luni.util.Util;
 
 /**
  * The URLConnection class is responsible for establishing a connection to an
@@ -505,18 +505,23 @@
      * @param field
      *            the field in question
      * @param defaultValue
-     *            the default value if no field is found
+     *            the default value if no field is found or the value is invalid
      * @return milliseconds since epoch
      * 
      * @see #ifModifiedSince
      * @see #setIfModifiedSince
      */
+    @SuppressWarnings("deprecation")
     public long getHeaderFieldDate(String field, long defaultValue) {
         String date = getHeaderField(field);
         if (date == null) {
             return defaultValue;
         }
-        return java.util.Date.parse(date);
+        try {
+            return Date.parse(date);
+        } catch (Exception e) {
+            return defaultValue;
+        }
     }
 
     /**

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/HashMap.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/HashMap.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/HashMap.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/HashMap.java Tue Jan  8 02:55:24 2008
@@ -68,29 +68,24 @@
         }
     }
 
-    static class HashMapIterator<E, KT, VT> implements Iterator<E> {
+    private static class AbstractMapIterator<K, V>  {
         private int position = 0;
-
         int expectedModCount;
+        Entry<K, V> futureEntry;
+        Entry<K, V> currentEntry;
+        Entry<K, V> prevEntry;
 
-        final MapEntry.Type<E, KT, VT> type;
-
-        boolean canRemove = false;
-
-        Entry<KT, VT> entry;
+        final HashMap<K, V> associatedMap;
 
-        Entry<KT, VT> lastEntry;
 
-        final HashMap<KT, VT> associatedMap;
-
-        HashMapIterator(MapEntry.Type<E, KT, VT> value, HashMap<KT, VT> hm) {
+        AbstractMapIterator(HashMap<K, V> hm) {
             associatedMap = hm;
-            type = value;
             expectedModCount = hm.modCount;
+            futureEntry = null;
         }
 
         public boolean hasNext() {
-            if (entry != null) {
+            if (futureEntry != null) {
                 return true;
             }
             while (position < associatedMap.elementData.length) {
@@ -103,52 +98,84 @@
             return false;
         }
 
-        void checkConcurrentMod() throws ConcurrentModificationException {
+        final void checkConcurrentMod() throws ConcurrentModificationException {
             if (expectedModCount != associatedMap.modCount) {
                 throw new ConcurrentModificationException();
             }
         }
 
-        public E next() {
+        final void makeNext() {
             checkConcurrentMod();
             if (!hasNext()) {
                 throw new NoSuchElementException();
             }
-
-            MapEntry<KT, VT> result;
-            if (entry == null) {
-                result = lastEntry = associatedMap.elementData[position++];
-                entry = lastEntry.next;
+            if (futureEntry == null) {
+                currentEntry = associatedMap.elementData[position++];
+                futureEntry = currentEntry.next;
+                prevEntry = null;
             } else {
-                if (lastEntry.next != entry) {
-                    lastEntry = lastEntry.next;
+                if(currentEntry!=null){
+                    prevEntry = currentEntry;
                 }
-                result = entry;
-                entry = entry.next;
+                currentEntry = futureEntry;
+                futureEntry = futureEntry.next;
             }
-            canRemove = true;
-            return type.get(result);
         }
 
-        public void remove() {
+        public final void remove() {
             checkConcurrentMod();
-            if (!canRemove) {
+            if (currentEntry==null) {
                 throw new IllegalStateException();
             }
-
-            canRemove = false;
-            associatedMap.modCount++;
-            if (lastEntry.next == entry) {
-                while (associatedMap.elementData[--position] == null) {
-                    // Do nothing
-                }
-                associatedMap.elementData[position] = associatedMap.elementData[position].next;
-                entry = null;
+            if(prevEntry==null){
+                int index = currentEntry.origKeyHash & (associatedMap.elementData.length - 1);
+                //assert associatedMap.elementData[index] == currentEntry;
+                associatedMap.elementData[index] = associatedMap.elementData[index].next;
             } else {
-                lastEntry.next = entry;
+                prevEntry.next = currentEntry.next;
             }
-            associatedMap.elementCount--;
+            currentEntry = null;
             expectedModCount++;
+            associatedMap.modCount++;
+            associatedMap.elementCount--;
+
+        }
+    }
+
+
+    private static class EntryIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<Map.Entry<K, V>> {
+
+        EntryIterator (HashMap<K, V> map) {
+            super(map);
+        }
+
+        public Map.Entry<K, V> next() {
+            makeNext();
+            return currentEntry;
+        }
+    }
+
+    private static class KeyIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<K> {
+
+        KeyIterator (HashMap<K, V> map) {
+            super(map);
+        }
+
+        public K next() {
+            makeNext();
+            return currentEntry.key;
+        }
+    }
+
+    private static class ValueIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<V> {
+
+        ValueIterator (HashMap<K, V> map) {
+            super(map);
+        }
+
+        public V next() {
+            makeNext();
+            return currentEntry.value;
         }
     }
 
@@ -175,9 +202,13 @@
 
         @Override
         public boolean remove(Object object) {
-            if (contains(object)) {
-                associatedMap.remove(((Map.Entry<?, ?>) object).getKey());
-                return true;
+            if (object instanceof Map.Entry) {
+                Map.Entry<?, ?> oEntry = (Map.Entry<?, ?>) object;
+                Entry<KT,VT> entry = associatedMap.getEntry(oEntry.getKey());
+                if(valuesEq(entry, oEntry)) {
+                    associatedMap.removeEntry(entry);
+                    return true;
+                }
             }
             return false;
         }
@@ -185,34 +216,29 @@
         @Override
         public boolean contains(Object object) {
             if (object instanceof Map.Entry) {
-                Object key = ((Map.Entry<?, ?>) object).getKey();
-                Entry<KT, VT> entry;
-                if (key == null) {
-                    entry = associatedMap.findNullKeyEntry();
-                } else {
-                    int hash = key.hashCode();
-                    int index = hash & (associatedMap.elementData.length - 1);
-                    entry = associatedMap.findNonNullKeyEntry(key, index, hash);
-                }
-                return entry == null ? false : entry.equals(object);
+                Map.Entry<?, ?> oEntry = (Map.Entry<?, ?>) object;
+                Entry entry = associatedMap.getEntry(oEntry.getKey());
+                return valuesEq(entry, oEntry);
             }
             return false;
         }
 
+        private static boolean valuesEq(Entry entry, Map.Entry<?, ?> oEntry) {
+            return (entry != null) &&
+                                   ((entry.value == null) ?
+                                    (oEntry.getValue() == null) :
+                                    (entry.value.equals(oEntry.getValue())));
+        }
+
         @Override
         public Iterator<Map.Entry<KT, VT>> iterator() {
-            return new HashMapIterator<Map.Entry<KT, VT>, KT, VT>(
-                    new MapEntry.Type<Map.Entry<KT, VT>, KT, VT>() {
-                        public Map.Entry<KT, VT> get(MapEntry<KT, VT> entry) {
-                            return entry;
-                        }
-                    }, associatedMap);
+            return new EntryIterator<KT,VT> (associatedMap);
         }
     }
 
     /**
      * Create a new element array
-     * 
+     *
      * @param s
      * @return Reference to the element array
      */
@@ -223,7 +249,7 @@
 
     /**
      * Constructs a new empty instance of HashMap.
-     * 
+     *
      */
     public HashMap() {
         this(DEFAULT_SIZE);
@@ -231,10 +257,10 @@
 
     /**
      * Constructs a new instance of HashMap with the specified capacity.
-     * 
+     *
      * @param capacity
      *            the initial capacity of this HashMap
-     * 
+     *
      * @exception IllegalArgumentException
      *                when the capacity is less than zero
      */
@@ -249,7 +275,7 @@
             throw new IllegalArgumentException();
         }
     }
-    
+
     private static final int calculateCapacity(int x) {
         if(x >= 1 << 30){
             return 1 << 30;
@@ -269,13 +295,13 @@
     /**
      * Constructs a new instance of HashMap with the specified capacity and load
      * factor.
-     * 
-     * 
+     *
+     *
      * @param capacity
      *            the initial capacity
      * @param loadFactor
      *            the initial load factor
-     * 
+     *
      * @exception IllegalArgumentException
      *                when the capacity is less than zero or the load factor is
      *                less or equal to zero
@@ -295,7 +321,7 @@
     /**
      * Constructs a new instance of HashMap containing the mappings from the
      * specified Map.
-     * 
+     *
      * @param map
      *            the mappings to add
      */
@@ -306,7 +332,7 @@
 
     /**
      * Removes all mappings from this HashMap, leaving it empty.
-     * 
+     *
      * @see #isEmpty
      * @see #size
      */
@@ -321,9 +347,9 @@
 
     /**
      * Answers a new HashMap with the same mappings and size as this HashMap.
-     * 
+     *
      * @return a shallow copy of this HashMap
-     * 
+     *
      * @see java.lang.Cloneable
      */
     @Override
@@ -355,7 +381,7 @@
 
     /**
      * Searches this HashMap for the specified key.
-     * 
+     *
      * @param key
      *            the object to search for
      * @return true if <code>key</code> is a key of this HashMap, false
@@ -363,20 +389,13 @@
      */
     @Override
     public boolean containsKey(Object key) {
-        Entry<K, V> m;
-        if (key == null) {
-            m = findNullKeyEntry();
-        } else {
-            int hash = key.hashCode();
-            int index = hash & (elementData.length - 1);
-            m = findNonNullKeyEntry(key, index, hash);
-        }
+        Entry<K, V> m = getEntry(key);
         return m != null;
     }
 
     /**
      * Searches this HashMap for the specified value.
-     * 
+     *
      * @param value
      *            the object to search for
      * @return true if <code>value</code> is a value of this HashMap, false
@@ -412,7 +431,7 @@
      * Answers a Set of the mappings contained in this HashMap. Each element in
      * the set is a Map.Entry. The set is backed by this HashMap so changes to
      * one are reflected by the other. The set does not support adding.
-     * 
+     *
      * @return a Set of the mappings
      */
     @Override
@@ -422,13 +441,21 @@
 
     /**
      * Answers the value of the mapping with the specified key.
-     * 
+     *
      * @param key
      *            the key
      * @return the value of the mapping with the specified key
      */
     @Override
     public V get(Object key) {
+        Entry<K, V> m = getEntry(key);
+        if (m != null) {
+            return m.value;
+        }
+        return null;
+    }
+
+    final Entry<K, V> getEntry(Object key) {
         Entry<K, V> m;
         if (key == null) {
             m = findNullKeyEntry();
@@ -437,10 +464,7 @@
             int index = hash & (elementData.length - 1);
             m = findNonNullKeyEntry(key, index, hash);
         }
-        if (m != null) {
-            return m.value;
-        }
-        return null;
+        return m;
     }
 
     final Entry<K,V> findNonNullKeyEntry(Object key, int index, int keyHash) {
@@ -450,7 +474,7 @@
         }
         return m;
     }
-  
+
     final Entry<K,V> findNullKeyEntry() {
         Entry<K,V> m = elementData[0];
         while (m != null && m.key != null)
@@ -460,9 +484,9 @@
 
     /**
      * Answers if this HashMap has no elements, a size of zero.
-     * 
+     *
      * @return true if this HashMap has no elements, false otherwise
-     * 
+     *
      * @see #size
      */
     @Override
@@ -474,7 +498,7 @@
      * Answers a Set of the keys contained in this HashMap. The set is backed by
      * this HashMap so changes to one are reflected by the other. The set does
      * not support adding.
-     * 
+     *
      * @return a Set of the keys
      */
     @Override
@@ -504,12 +528,7 @@
 
                 @Override
                 public Iterator<K> iterator() {
-                    return new HashMapIterator<K, K, V>(
-                            new MapEntry.Type<K, K, V>() {
-                                public K get(MapEntry<K, V> entry) {
-                                    return entry.key;
-                                }
-                            }, HashMap.this);
+                    return new KeyIterator<K,V> (HashMap.this);
                 }
             };
         }
@@ -518,7 +537,7 @@
 
     /**
      * Maps the specified key to the specified value.
-     * 
+     *
      * @param key
      *            the key
      * @param value
@@ -579,7 +598,7 @@
      * Copies all the mappings in the given map to this map. These mappings will
      * replace all mappings that this map had for any of the keys currently in
      * the given map.
-     * 
+     *
      * @param map
      *            the Map to copy mappings from
      * @throws NullPointerException
@@ -626,7 +645,7 @@
 
     /**
      * Removes a mapping with the specified key from this HashMap.
-     * 
+     *
      * @param key
      *            the key of the mapping to remove
      * @return the value of the removed mapping or null if key is not a key in
@@ -641,7 +660,23 @@
         return null;
     }
 
-    Entry<K, V> removeEntry(Object key) {
+    final void removeEntry(Entry<K, V> entry) {
+        int index = entry.origKeyHash & (elementData.length - 1);
+        Entry<K, V> m = elementData[index];
+        if (m == entry) {
+            elementData[index] = entry.next;
+        } else {
+            while (m.next != entry && m.next != null) {
+                m = m.next;
+            }
+            m.next = entry.next;
+
+        }
+        modCount++;
+        elementCount--;
+    }
+
+    final Entry<K, V> removeEntry(Object key) {
         int index = 0;
         Entry<K, V> entry;
         Entry<K, V> last = null;
@@ -675,7 +710,7 @@
 
     /**
      * Answers the number of mappings in this HashMap.
-     * 
+     *
      * @return the number of mappings in this HashMap
      */
     @Override
@@ -687,7 +722,7 @@
      * Answers a Collection of the values contained in this HashMap. The
      * collection is backed by this HashMap so changes to one are reflected by
      * the other. The collection does not support adding.
-     * 
+     *
      * @return a Collection of the values
      */
     @Override
@@ -711,12 +746,7 @@
 
                 @Override
                 public Iterator<V> iterator() {
-                    return new HashMapIterator<V, K, V>(
-                            new MapEntry.Type<V, K, V>() {
-                                public V get(MapEntry<K, V> entry) {
-                                    return entry.value;
-                                }
-                            }, HashMap.this);
+                    return new ValueIterator<K,V> (HashMap.this);
                 }
             };
         }

Modified: harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/LinkedHashMap.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/LinkedHashMap.java?rev=609928&r1=609927&r2=609928&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/LinkedHashMap.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/luni/src/main/java/java/util/LinkedHashMap.java Tue Jan  8 02:55:24 2008
@@ -107,62 +107,47 @@
         putAll(m);
     }
 
-    static final class LinkedHashIterator<E, KT, VT> extends
-            HashMapIterator<E, KT, VT> {
-        LinkedHashIterator(MapEntry.Type<E, KT, VT> value,
-                LinkedHashMap<KT, VT> hm) {
-            super(value, hm);
-            entry = hm.head;
+    private static class AbstractMapIterator<K, V>  {
+        int expectedModCount;
+        LinkedHashMapEntry<K, V>  futureEntry;
+        LinkedHashMapEntry<K, V>  currentEntry;
+        final LinkedHashMap<K, V> associatedMap;
+
+        AbstractMapIterator(LinkedHashMap<K, V> map) {
+            expectedModCount = map.modCount;
+            futureEntry = map.head;
+            associatedMap = map;
         }
 
-        @Override
         public boolean hasNext() {
-            return (entry != null);
+            return (futureEntry != null);
         }
 
-        @Override
-        public E next() {
+        final void checkConcurrentMod() throws ConcurrentModificationException {
+            if (expectedModCount != associatedMap.modCount) {
+                throw new ConcurrentModificationException();
+            }
+        }
+
+        final void makeNext() {
             checkConcurrentMod();
             if (!hasNext()) {
                 throw new NoSuchElementException();
             }
-            E result = type.get(entry);
-            lastEntry = entry;
-            entry = ((LinkedHashMapEntry<KT, VT>) entry).chainForward;
-            canRemove = true;
-            return result;
+            currentEntry = futureEntry;
+            futureEntry = futureEntry.chainForward;
         }
 
-        @Override
         public void remove() {
             checkConcurrentMod();
-            if (!canRemove) {
+            if (currentEntry==null) {
                 throw new IllegalStateException();
             }
-
-            canRemove = false;
-            associatedMap.modCount++;
-
-            int index = (lastEntry.key == null) ? 0
-                    : (lastEntry.key.hashCode() & 0x7FFFFFFF)
-                            % associatedMap.elementData.length;
-            LinkedHashMapEntry<KT, VT> m = (LinkedHashMapEntry<KT, VT>) associatedMap.elementData[index];
-            if (m == lastEntry) {
-                associatedMap.elementData[index] = lastEntry.next;
-            } else {
-                while (m.next != null) {
-                    if (m.next == lastEntry) {
-                        break;
-                    }
-                    m = (LinkedHashMapEntry<KT, VT>) m.next;
-                }
-                // assert m.next == entry
-                m.next = lastEntry.next;
-            }
-            LinkedHashMapEntry<KT, VT> lhme = (LinkedHashMapEntry<KT, VT>) lastEntry;
-            LinkedHashMapEntry<KT, VT> p = lhme.chainBackward;
-            LinkedHashMapEntry<KT, VT> n = lhme.chainForward;
-            LinkedHashMap<KT, VT> lhm = (LinkedHashMap<KT, VT>) associatedMap;
+            associatedMap.removeEntry(currentEntry);
+            LinkedHashMapEntry<K, V> lhme =  currentEntry;
+            LinkedHashMapEntry<K, V> p = lhme.chainBackward;
+            LinkedHashMapEntry<K, V> n = lhme.chainForward;
+            LinkedHashMap<K, V> lhm = associatedMap;
             if (p != null) {
                 p.chainForward = n;
                 if (n != null) {
@@ -178,11 +163,47 @@
                     lhm.tail = null;
                 }
             }
-            associatedMap.elementCount--;
+            currentEntry = null;
             expectedModCount++;
         }
     }
 
+    private static class EntryIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<Map.Entry<K, V>> {
+
+        EntryIterator (LinkedHashMap<K, V> map) {
+            super(map);
+        }
+
+        public Map.Entry<K, V> next() {
+            makeNext();
+            return currentEntry;
+        }
+    }
+
+    private static class KeyIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<K> {
+
+        KeyIterator (LinkedHashMap<K, V> map) {
+            super(map);
+        }
+
+        public K next() {
+            makeNext();
+            return currentEntry.key;
+        }
+    }
+
+    private static class ValueIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<V> {
+
+        ValueIterator (LinkedHashMap<K, V> map) {
+            super(map);
+        }
+
+        public V next() {
+            makeNext();
+            return currentEntry.value;
+        }
+    }
+
     static final class LinkedHashMapEntrySet<KT, VT> extends
             HashMapEntrySet<KT, VT> {
         public LinkedHashMapEntrySet(LinkedHashMap<KT, VT> lhm) {
@@ -191,12 +212,7 @@
 
         @Override
         public Iterator<Map.Entry<KT, VT>> iterator() {
-            return new LinkedHashIterator<Map.Entry<KT, VT>, KT, VT>(
-                    new MapEntry.Type<Map.Entry<KT, VT>, KT, VT>() {
-                        public Map.Entry<KT, VT> get(MapEntry<KT, VT> entry) {
-                            return entry;
-                        }
-                    }, (LinkedHashMap<KT, VT>) hashMap());
+            return new EntryIterator<KT,VT>((LinkedHashMap<KT, VT>) hashMap());
         }
     }
 
@@ -494,12 +510,7 @@
 
                 @Override
                 public Iterator<K> iterator() {
-                    return new LinkedHashIterator<K, K, V>(
-                            new MapEntry.Type<K, K, V>() {
-                                public K get(MapEntry<K, V> entry) {
-                                    return entry.key;
-                                }
-                            }, LinkedHashMap.this);
+                    return new KeyIterator<K,V>(LinkedHashMap.this);
                 }
             };
         }
@@ -534,12 +545,7 @@
 
                 @Override
                 public Iterator<V> iterator() {
-                    return new LinkedHashIterator<V, K, V>(
-                            new MapEntry.Type<V, K, V>() {
-                                public V get(MapEntry<K, V> entry) {
-                                    return entry.value;
-                                }
-                            }, LinkedHashMap.this);
+                    return new ValueIterator<K,V>(LinkedHashMap.this);
                 }
             };
         }