Initial Contribution
diff --git a/awt/javax/imageio/stream/FileCacheImageInputStream.java b/awt/javax/imageio/stream/FileCacheImageInputStream.java
new file mode 100644
index 0000000..47bc189
--- /dev/null
+++ b/awt/javax/imageio/stream/FileCacheImageInputStream.java
@@ -0,0 +1,131 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.stream;
+
+import java.io.*;
+
+/**
+ * The FileCacheImageInputStream class is an implementation of
+ * ImageInputStream which reads from its InputStream
+ * and uses a temporary file as a cache. 
+ */
+public class FileCacheImageInputStream extends ImageInputStreamImpl {
+    
+    /** The is. */
+    private InputStream is;
+    
+    /** The file. */
+    private File file;
+    
+    /** The raf. */
+    private RandomAccessFile raf;
+
+
+    /**
+     * Instantiates a new FileCacheImageInputStream from
+     * the specified InputStream and using the specified 
+     * File as its cache directory.
+     * 
+     * @param stream the InputStream for reading.
+     * @param cacheDir the cache directory where the chache file
+     * will be created.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public FileCacheImageInputStream(InputStream stream, File cacheDir) throws IOException {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream == null!");
+        }
+        is = stream;
+
+        if (cacheDir == null || cacheDir.isDirectory()) {
+            file = File.createTempFile(FileCacheImageOutputStream.IIO_TEMP_FILE_PREFIX, null, cacheDir);
+            file.deleteOnExit();
+        } else {
+            throw new IllegalArgumentException("Not a directory!");
+        }
+
+        raf = new RandomAccessFile(file, "rw");
+    }
+
+    @Override
+    public int read() throws IOException {
+        bitOffset = 0;
+
+        if (streamPos >= raf.length()) {
+            int b = is.read();
+
+            if (b < 0) {
+                return -1;
+            }
+
+            raf.seek(streamPos++);
+            raf.write(b);
+            return b;
+        }
+
+        raf.seek(streamPos++);
+        return raf.read();
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        bitOffset = 0;
+
+        if (streamPos >= raf.length()) {
+            int nBytes = is.read(b, off, len);
+
+            if (nBytes < 0) {
+                return -1;
+            }
+
+            raf.seek(streamPos);
+            raf.write(b, off, nBytes);
+            streamPos += nBytes;
+            return nBytes;
+        }
+
+        raf.seek(streamPos);
+        int nBytes = raf.read(b, off, len);
+        streamPos += nBytes;
+        return nBytes;
+    }
+
+    @Override
+    public boolean isCached() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedFile() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedMemory() {
+        return false;
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+        raf.close();
+        file.delete();
+    }
+}
diff --git a/awt/javax/imageio/stream/FileCacheImageOutputStream.java b/awt/javax/imageio/stream/FileCacheImageOutputStream.java
new file mode 100644
index 0000000..ae48585
--- /dev/null
+++ b/awt/javax/imageio/stream/FileCacheImageOutputStream.java
@@ -0,0 +1,184 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.stream;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+
+/**
+ * The FileCacheImageOutputStream class is an implementation of 
+ * ImageOutputStream that writes to its OutputStream
+ * using a temporary file as a cache. 
+ */
+public class FileCacheImageOutputStream extends ImageOutputStreamImpl {
+    
+    /** The Constant IIO_TEMP_FILE_PREFIX. */
+    static final String IIO_TEMP_FILE_PREFIX = "iioCache";
+    
+    /** The Constant MAX_BUFFER_LEN. */
+    static final int MAX_BUFFER_LEN = 1048575; // 1 MB - is it not too much?
+
+    /** The os. */
+    private OutputStream os;
+    
+    /** The file. */
+    private File file;
+    
+    /** The raf. */
+    private RandomAccessFile raf;
+
+    /**
+     * Instantiates a FileCacheImageOutputStream.
+     * 
+     * @param stream the OutputStream for writing.
+     * @param cacheDir the cache directory where the chache file
+     * will be created.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public FileCacheImageOutputStream(OutputStream stream, File cacheDir) throws IOException {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream == null!");
+        }
+        os = stream;
+
+        if (cacheDir == null || cacheDir.isDirectory()) {
+            file = File.createTempFile(IIO_TEMP_FILE_PREFIX, null, cacheDir);
+            file.deleteOnExit();
+        } else {
+            throw new IllegalArgumentException("Not a directory!");
+        }
+
+        raf = new RandomAccessFile(file, "rw");
+    }
+
+    @Override
+    public void close() throws IOException {
+        flushBefore(raf.length());
+        super.close();
+        raf.close();
+        file.delete();
+    }
+
+    @Override
+    public boolean isCached() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedFile() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedMemory() {
+        return false;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        flushBits(); // See the flushBits method description
+        
+        raf.write(b);
+        streamPos++;
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        flushBits(); // See the flushBits method description
+
+        raf.write(b, off, len);
+        streamPos += len;
+    }
+
+    @Override
+    public int read() throws IOException {
+        bitOffset = 0; // Should reset
+
+        int res = raf.read();
+        if (res >= 0) {
+            streamPos++;
+        }
+
+        return res;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        bitOffset = 0;
+
+        int numRead = raf.read(b, off, len);
+        if (numRead > 0) {
+            streamPos += numRead;
+        }
+
+        return numRead;
+    }
+
+    @Override
+    public void flushBefore(long pos) throws IOException {
+        long readFromPos = flushedPos;
+        super.flushBefore(pos);
+
+        long bytesToRead = pos - readFromPos;
+        raf.seek(readFromPos);
+
+        if (bytesToRead < MAX_BUFFER_LEN) {
+            byte buffer[] = new byte[(int)bytesToRead];
+            raf.readFully(buffer);
+            os.write(buffer);
+        } else {
+            byte buffer[] = new byte[MAX_BUFFER_LEN];
+            while (bytesToRead > 0) {
+                int count = (int) Math.min(MAX_BUFFER_LEN, bytesToRead);
+                raf.readFully(buffer, 0, count);
+                os.write(buffer, 0, count);
+                bytesToRead -= count;
+            }
+        }
+
+        os.flush();
+
+        if (pos != streamPos) {
+            raf.seek(streamPos); // Reset the position
+        }
+    }
+
+    @Override
+    public void seek(long pos) throws IOException {
+        if (pos < flushedPos) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        raf.seek(pos);
+        streamPos = raf.getFilePointer();        
+        bitOffset = 0;
+    }
+
+    @Override
+    public long length() {
+        try {
+            return raf.length();
+        } catch(IOException e) {
+            return -1L;
+        }
+    }
+}
diff --git a/awt/javax/imageio/stream/FileImageInputStream.java b/awt/javax/imageio/stream/FileImageInputStream.java
new file mode 100644
index 0000000..6680ae0
--- /dev/null
+++ b/awt/javax/imageio/stream/FileImageInputStream.java
@@ -0,0 +1,115 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.stream;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/**
+ * The FileImageInputStream class implements ImageInputStream 
+ * and obtains its input data from a File or RandomAccessFile. 
+ */
+public class FileImageInputStream extends ImageInputStreamImpl {
+    
+    /** The raf. */
+    RandomAccessFile raf;
+
+    /**
+     * Instantiates a new FileImageInputStream from the specified File.
+     * 
+     * @param f the File of input data.
+     * 
+     * @throws FileNotFoundException if the specified file 
+     * doesn't exist.
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    @SuppressWarnings({"DuplicateThrows"})
+    public FileImageInputStream(File f) throws FileNotFoundException, IOException {
+        if (f == null) {
+            throw new IllegalArgumentException("f == null!");
+        }
+
+        raf = new RandomAccessFile(f, "r");
+    }
+
+    /**
+     * Instantiates a new FileImageInputStream from the specified 
+     * RandomAccessFile.
+     * 
+     * @param raf the RandomAccessFile of input data.
+     */
+    public FileImageInputStream(RandomAccessFile raf) {
+        if (raf == null) {
+            throw new IllegalArgumentException("raf == null!");
+        }
+
+        this.raf = raf;
+    }
+
+    @Override
+    public int read() throws IOException {
+        bitOffset = 0;
+
+        int res = raf.read();
+        if (res != -1) {
+            streamPos++;
+        }
+        return res;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        bitOffset = 0;
+
+        int numRead = raf.read(b, off, len);
+        if (numRead >= 0) {
+            streamPos += numRead;
+        }
+
+        return numRead;
+    }
+
+    @Override
+    public long length() {
+        try {
+            return raf.length();
+        } catch(IOException e) {
+            return -1L;
+        }
+    }
+
+    @Override
+    public void seek(long pos) throws IOException {
+        if (pos < getFlushedPosition()) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        raf.seek(pos);
+        streamPos = raf.getFilePointer();
+        bitOffset = 0;
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+        raf.close();
+    }
+}
diff --git a/awt/javax/imageio/stream/FileImageOutputStream.java b/awt/javax/imageio/stream/FileImageOutputStream.java
new file mode 100644
index 0000000..eaafe14
--- /dev/null
+++ b/awt/javax/imageio/stream/FileImageOutputStream.java
@@ -0,0 +1,123 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  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.stream;
+
+import java.io.*;
+
+/**
+ * The FileImageOutputStream class implements ImageOutputStream 
+ * and writes the output data to a File or RandomAccessFile. 
+ */
+public class FileImageOutputStream extends ImageOutputStreamImpl {
+
+    /** The file. */
+    RandomAccessFile file;
+
+    /**
+     * Instantiates a new FileImageOutputStream with the specified
+     * File.
+     * 
+     * @param f the output File.
+     * 
+     * @throws FileNotFoundException if the file not found.
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public FileImageOutputStream(File f) throws FileNotFoundException, IOException {
+        this(f != null
+                ? new RandomAccessFile(f, "rw")
+                : null);
+    }
+
+    /**
+     * Instantiates a new FileImageOutputStream with the specified
+     * RandomAccessFile.
+     * 
+     * @param raf the output RandomAccessFile.
+     */
+    public FileImageOutputStream(RandomAccessFile raf) {
+        if (raf == null) {
+            throw new IllegalArgumentException("file should not be NULL");
+        }
+        file = raf;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        checkClosed();
+        // according to the spec for ImageOutputStreamImpl#flushBits()
+        flushBits();
+        file.write(b);
+        streamPos++;
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        checkClosed();
+        // according to the spec for ImageOutputStreamImpl#flushBits()
+        flushBits();
+        file.write(b, off, len);
+        streamPos += len;
+    }
+
+    @Override
+    public int read() throws IOException {
+        checkClosed();
+        int rt = file.read();
+        if (rt != -1) {
+            streamPos++;
+        }
+        return rt;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        checkClosed();
+        int rt = file.read(b, off, len);
+        if (rt != -1) {
+            streamPos += rt;
+        }
+        return rt;
+    }
+
+    @Override
+    public long length() {
+        try {
+            checkClosed();
+            return file.length();
+        } catch(IOException e) {
+            return super.length(); // -1L
+        }
+    }
+
+    @Override
+    public void seek(long pos) throws IOException {
+        //-- checkClosed() is performed in super.seek()
+        super.seek(pos);
+        file.seek(pos);
+        streamPos = file.getFilePointer();
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+        file.close();
+    }
+}
diff --git a/awt/javax/imageio/stream/IIOByteBuffer.java b/awt/javax/imageio/stream/IIOByteBuffer.java
new file mode 100644
index 0000000..961a7b3
--- /dev/null
+++ b/awt/javax/imageio/stream/IIOByteBuffer.java
@@ -0,0 +1,111 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio.stream;
+
+/** 
+* @author Sergey I. Salishev
+* @version $Revision: 1.2 $
+*/
+
+/**
+ * The IIOByteBuffer class represents a byte array with offset and 
+ * length that is used by ImageInputStream for obtaining a sequence 
+ * of bytes.
+ */
+public class IIOByteBuffer {
+    
+    /** The data. */
+    private byte[] data;
+    
+    /** The offset. */
+    private int offset;
+    
+    /** The length. */
+    private int length;
+
+    /**
+     * Instantiates a new IIOByteBuffer.
+     * 
+     * @param data the byte array.
+     * @param offset the offset in the array.
+     * @param length the length of array.
+     */
+    public IIOByteBuffer(byte[] data, int offset, int length) {
+        this.data = data;
+        this.offset = offset;
+        this.length = length;
+    }
+
+    /**
+     * Gets the byte array of this IIOByteBuffer.
+     * 
+     * @return the byte array.
+     */
+    public byte[] getData() {
+        return data;
+    }
+
+    /**
+     * Gets the length in the array which will be used.
+     * 
+     * @return the length of the data.
+     */
+    public int getLength() {
+        return length;
+    }
+
+    /**
+     * Gets the offset of this IIOByteBuffer.
+     * 
+     * @return the offset of this IIOByteBuffer.
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Sets the new data array to this IIOByteBuffer object.
+     * 
+     * @param data the new data array.
+     */
+    public void setData(byte[] data) {
+        this.data = data;
+    }
+
+    /**
+     * Sets the length of data which will be used.
+     * 
+     * @param length the new length.
+     */
+    public void setLength(int length) {
+        this.length = length;
+    }
+
+    /**
+     * Sets the offset in the data array of this IIOByteBuffer.
+     * 
+     * @param offset the new offset.
+     */
+    public void setOffset(int offset) {
+        this.offset = offset;
+    }
+}
+
diff --git a/awt/javax/imageio/stream/ImageInputStream.java b/awt/javax/imageio/stream/ImageInputStream.java
new file mode 100644
index 0000000..771e9ff
--- /dev/null
+++ b/awt/javax/imageio/stream/ImageInputStream.java
@@ -0,0 +1,485 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio.stream;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.nio.ByteOrder;
+
+/**
+ * The ImageInputStream represents input stream interface that is 
+ * used by ImageReaders.
+ */
+public interface ImageInputStream extends DataInput {
+
+    /**
+     * Sets the specified byte order for reading of data values 
+     * from this stream. 
+     * 
+     * @param byteOrder the byte order.
+     */
+    void setByteOrder(ByteOrder byteOrder);
+
+    /**
+     * Gets the byte order. 
+     * 
+     * @return the byte order.
+     */
+    ByteOrder getByteOrder();
+
+    /**
+     * Reads a byte from the stream.
+     * 
+     * @return the byte of the stream, or -1 for EOF indicating. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int read() throws IOException;
+
+    /**
+     * Reads number of bytes which is equal to the specified array's length
+     * and stores a result to this array.
+     * 
+     * @param b the byte array.
+     * 
+     * @return the number of read bytes, or -1 indicated EOF.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int read(byte[] b) throws IOException;
+
+    /**
+     * Reads the number of bytes specified by len parameter from 
+     * the stream and stores a result to the specified array
+     * with the specified offset.
+     * 
+     * @param b the byte array.
+     * @param off the offset.
+     * @param len the number of bytes to be read.
+     * 
+     * @return the number of read bytes, or -1 indicated EOF.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int read(byte[] b, int off, int len) throws IOException;
+
+    /**
+     * Reads the number of bytes specified by len parameter 
+     * from the stream, and modifies the specified IIOByteBuffer 
+     * with the byte array, offset, and length.
+     * 
+     * @param buf the IIOByteBuffer.
+     * @param len the number of bytes to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readBytes(IIOByteBuffer buf, int len) throws IOException;
+
+    /**
+     * Reads a byte from the stream and returns a boolean true value 
+     * if it is non zero, false if it is zero.
+     * 
+     * @return a boolean value for read byte. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    boolean readBoolean() throws IOException;
+
+    /**
+     * Reads a byte from the stream and returns its value
+     * as signed byte.
+     * 
+     * @return a signed byte value for read byte. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    byte readByte() throws IOException;
+
+    /**
+     * Reads a byte from the stream and returns its value
+     * as int.
+     * 
+     * @return a unsigned byte value for read byte as int. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int readUnsignedByte() throws IOException;
+
+    /**
+     * Reads 2 bytes from the stream, and returns the result 
+     * as a short.
+     * 
+     * @return the signed short value from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    short readShort() throws IOException;
+
+    /**
+     * Reads 2 bytes from the stream and returns its value
+     * as an unsigned short.
+     * 
+     * @return a unsigned short value coded in an int. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int readUnsignedShort() throws IOException;
+
+    /**
+     * Reads 2 bytes from the stream and returns their 
+     * unsigned char value.
+     * 
+     * @return the unsigned char value.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    char readChar() throws IOException;
+
+    /**
+     * Reads 4 bytes from the stream, and returns the result 
+     * as an int.
+     * 
+     * @return the signed int value from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int readInt() throws IOException;
+
+    /**
+     * Reads 4 bytes from the stream and returns its value
+     * as long.
+     * 
+     * @return a unsigned int value as long. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long readUnsignedInt() throws IOException;
+
+    /**
+     * Reads 8 bytes from the stream, and returns the result 
+     * as a long.
+     * 
+     * @return the long value from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long readLong() throws IOException;
+
+    /**
+     * Reads 4 bytes from the stream, and returns the result 
+     * as a float.
+     * 
+     * @return the float value from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    float readFloat() throws IOException;
+
+    /**
+     * Reads 8 bytes from the stream, and returns the result 
+     * as a double.
+     * 
+     * @return the double value from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    double readDouble() throws IOException;
+
+    /**
+     * Reads a line from the stream.
+     * 
+     * @return the string contained the line from the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    String readLine() throws IOException;
+
+    /**
+     * Reads bytes from the stream in a string that has been encoded 
+     * in a modified UTF-8 format.
+     * 
+     * @return the string read from stream and modified UTF-8 format.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    String readUTF() throws IOException;
+
+    /**
+     * Reads the specified number of bytes from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param b the byte array.
+     * @param off the offset.
+     * @param len the number of bytes to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(byte[] b, int off, int len) throws IOException;
+
+    /**
+     * Reads number of bytes from the stream which is equal to 
+     * the specified array's length, and stores them into 
+     * this array.
+     * 
+     * @param b the byte array.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(byte[] b) throws IOException;
+
+    /**
+     * Reads the specified number of shorts from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param s the short array.
+     * @param off the offset.
+     * @param len the number of shorts to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(short[] s, int off, int len) throws IOException;
+
+    /**
+     * Reads the specified number of chars from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param c the char array.
+     * @param off the offset.
+     * @param len the number of chars to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(char[] c, int off, int len) throws IOException;
+
+    /**
+     * Reads the specified number of ints from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param i the int array.
+     * @param off the offset.
+     * @param len the number of ints to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(int[] i, int off, int len) throws IOException;
+
+    /**
+     * Reads the specified number of longs from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param l the long array.
+     * @param off the offset.
+     * @param len the number of longs to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(long[] l, int off, int len) throws IOException;
+
+    /**
+     * Reads the specified number of floats from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param f the float array.
+     * @param off the offset.
+     * @param len the number of floats to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(float[] f, int off, int len) throws IOException;
+
+    /**
+     * Reads the specified number of doubles from the stream, 
+     * and stores the result into the specified array starting at 
+     * the specified index offset. 
+     * 
+     * @param d the double array.
+     * @param off the offset.
+     * @param len the number of doubles to be read.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void readFully(double[] d, int off, int len) throws IOException;
+
+    /**
+     * Gets the stream position.
+     * 
+     * @return the stream position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long getStreamPosition() throws IOException;
+
+    /**
+     * Gets the bit offset.
+     * 
+     * @return the bit offset.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int getBitOffset() throws IOException;
+
+    /**
+     * Sets the bit offset to an integer between 0 and 7. 
+     * 
+     * @param bitOffset the bit offset.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void setBitOffset(int bitOffset) throws IOException;
+
+    /**
+     * Reads a bit from the stream and returns the value 0 or 1.
+     * 
+     * @return the value of single bit: 0 or 1.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int readBit() throws IOException;
+
+    /**
+     * Read the specified number of bits and returns their values as long.
+     * 
+     * @param numBits the number of bits to be read.
+     * 
+     * @return the bit string as a long.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long readBits(int numBits) throws IOException;
+
+    /**
+     * Returns the length of the stream. 
+     *  
+     * @return the length of the stream, or -1 if unknown. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long length() throws IOException;
+
+    /**
+     * Skipes the specified number of bytes by moving stream position. 
+     * 
+     * @param n the number of bytes.
+     * 
+     * @return the actual skipped number of bytes.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    int skipBytes(int n) throws IOException;
+
+    /**
+     * Skipes the specified number of bytes by moving stream position. 
+     * 
+     * @param n the number of bytes.
+     * 
+     * @return the actual skipped number of bytes.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    long skipBytes(long n) throws IOException;
+
+    /**
+     * Sets the current stream position to the specified location. 
+     * 
+     * @param pos a file pointer position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void seek(long pos) throws IOException;
+
+    /**
+     * Marks a position in the stream to be returned to by a subsequent 
+     * call to reset. 
+     */
+    void mark();
+
+    /**
+     * Returns the file pointer to its previous position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void reset() throws IOException;
+
+    /**
+     * Flushes the initial position in this stream prior to the
+     * specified stream position.
+     * 
+     * @param pos the position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void flushBefore(long pos) throws IOException;
+
+    /**
+     * Flushes the initial position in this stream prior to the
+     * current stream position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void flush() throws IOException;
+
+    /**
+     * Gets the flushed position.
+     * 
+     * @return the flushed position.
+     */
+    long getFlushedPosition();
+
+    /**
+     * Returns true if this ImageInputStream caches data in order 
+     * to allow seeking backwards.
+     * 
+     * @return true if this ImageInputStream caches data in order 
+     * to allow seeking backwards, false otherwise.
+     */
+    boolean isCached();
+
+    /**
+     * Returns true if this ImageInputStream caches data in order 
+     * to allow seeking backwards, and keeps it in memory.
+     * 
+     * @return true if this ImageInputStream caches data in order 
+     * to allow seeking backwards, and keeps it in memory.
+     */
+    boolean isCachedMemory();
+
+    /**
+     * Returns true if this ImageInputStream caches data in order 
+     * to allow seeking backwards, and keeps it in a temporary file.
+     * 
+     * @return true if this ImageInputStream caches data in order 
+     * to allow seeking backwards, and keeps it in a temporary file.
+     */
+    boolean isCachedFile();
+
+    /**
+     * Closes this stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void close() throws IOException;
+}
diff --git a/awt/javax/imageio/stream/ImageInputStreamImpl.java b/awt/javax/imageio/stream/ImageInputStreamImpl.java
new file mode 100644
index 0000000..83ac13a
--- /dev/null
+++ b/awt/javax/imageio/stream/ImageInputStreamImpl.java
@@ -0,0 +1,394 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  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.stream;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.ByteOrder;
+
+/**
+ * The ImageInputStreamImpl abstract class implements
+ * the ImageInputStream interface.
+ */
+public abstract class ImageInputStreamImpl implements ImageInputStream {
+
+    /** The byte order. */
+    protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
+
+    /** The stream position. */
+    protected long streamPos = 0;
+    
+    /** The flushed position. */
+    protected long flushedPos = 0;
+    
+    /** The bit offset. */
+    protected int bitOffset = 0;
+
+    /** The closed. */
+    private boolean closed = false;
+
+    /** The position stack. */
+    private final PositionStack posStack = new PositionStack();
+
+    /**
+     * Instantiates a new ImageInputStreamImpl.
+     */
+    public ImageInputStreamImpl() {}
+
+    /**
+     * Check if the stream is closed and if true, throws an IOException.
+     * 
+     * @throws IOException Signals that the stream is closed.
+     */
+    protected final void checkClosed() throws IOException {
+        if (closed) {
+            throw new IOException("stream is closed");
+        }
+    }
+
+    public void setByteOrder(ByteOrder byteOrder) {
+        this.byteOrder = byteOrder;
+    }
+
+    public ByteOrder getByteOrder() {
+        return byteOrder;
+    }
+
+    public abstract int read() throws IOException;
+
+    public int read(byte[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    public abstract int read(byte[] b, int off, int len) throws IOException;
+
+    public void readBytes(IIOByteBuffer buf, int len) throws IOException {
+        if (buf == null) {
+            throw new NullPointerException("buffer is NULL");
+        }
+
+        byte[] b = new byte[len];
+        len = read(b, 0, b.length);
+
+        buf.setData(b);
+        buf.setOffset(0);
+        buf.setLength(len);
+    }
+
+    public boolean readBoolean() throws IOException {
+        int b = read();
+        if (b < 0) {
+            throw new EOFException("EOF reached");
+        }
+        return b != 0;
+    }
+
+    public byte readByte() throws IOException {
+        int b = read();
+        if (b < 0) {
+            throw new EOFException("EOF reached");
+        }
+        return (byte) b;
+    }
+
+    public int readUnsignedByte() throws IOException {
+        int b = read();
+        if (b < 0) {
+            throw new EOFException("EOF reached");
+        }
+        return b;
+    }
+
+    public short readShort() throws IOException {
+        int b1 = read();
+        int b2 = read();
+
+        if (b1 < 0 || b2 < 0) {
+            throw new EOFException("EOF reached");
+        }
+
+        return byteOrder == ByteOrder.BIG_ENDIAN ?
+                (short) ((b1 << 8) | (b2 & 0xff)) :
+                (short) ((b2 << 8) | (b1 & 0xff));
+    }
+
+    public int readUnsignedShort() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public char readChar() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public int readInt() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long readUnsignedInt() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long readLong() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public float readFloat() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public double readDouble() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public String readLine() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public String readUTF() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(byte[] b, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(byte[] b) throws IOException {
+        readFully(b, 0, b.length);
+    }
+
+    public void readFully(short[] s, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(char[] c, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(int[] i, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(long[] l, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(float[] f, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void readFully(double[] d, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long getStreamPosition() throws IOException {
+        checkClosed();
+        return streamPos;
+    }
+
+    public int getBitOffset() throws IOException {
+        checkClosed();
+        return bitOffset;
+    }
+
+    public void setBitOffset(int bitOffset) throws IOException {
+        checkClosed();
+        this.bitOffset = bitOffset;
+    }
+
+    public int readBit() throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long readBits(int numBits) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long length() {
+        return -1L;
+    }
+
+    public int skipBytes(int n) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public long skipBytes(long n) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void seek(long pos) throws IOException {
+        checkClosed();
+        if (pos < getFlushedPosition()) {
+            throw new IllegalArgumentException("trying to seek before flushed pos");
+        }
+        bitOffset = 0;
+        streamPos = pos;
+    }
+
+    public void mark() {
+        try {
+            posStack.push(getStreamPosition());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Stream marking error");
+        }
+    }
+
+    public void reset() throws IOException {
+        //-- TODO bit pos
+        if (!posStack.isEmpty()) {
+            long p = posStack.pop();
+            if (p < flushedPos) {
+                throw new IOException("marked position lies in the flushed portion of the stream");
+            }
+            seek(p);
+        }
+    }
+
+    public void flushBefore(long pos) throws IOException {
+        if (pos > getStreamPosition()) {
+            throw new IndexOutOfBoundsException("Trying to flush outside of current position");
+        }
+        if (pos < flushedPos) {
+            throw new IndexOutOfBoundsException("Trying to flush within already flushed portion");
+        }
+        flushedPos = pos;
+        //-- TODO implement
+    }
+
+    public void flush() throws IOException {
+        flushBefore(getStreamPosition());
+    }
+
+    public long getFlushedPosition() {
+        return flushedPos;
+    }
+
+    public boolean isCached() {
+        return false; //def
+    }
+
+    public boolean isCachedMemory() {
+        return false; //def
+    }
+
+    public boolean isCachedFile() {
+        return false; //def
+    }
+
+    public void close() throws IOException {
+        checkClosed();
+        closed = true;
+
+    }
+
+    /**
+     * Finalizes this object.
+     * 
+     * @throws Throwable if an error occurs.
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        if (!closed) {
+            try {
+                close();
+            } finally {
+                super.finalize();
+            }
+        }
+    }
+
+    /**
+     * The Class PositionStack.
+     */
+    private static class PositionStack {
+        
+        /** The Constant SIZE. */
+        private static final int SIZE = 10;
+
+        /** The values. */
+        private long[] values = new long[SIZE];
+        
+        /** The pos. */
+        private int pos = 0;
+
+
+        /**
+         * Push.
+         * 
+         * @param v the v
+         */
+        void push(long v) {
+            if (pos >= values.length) {
+                ensure(pos+1);
+            }
+            values[pos++] = v;
+        }
+
+        /**
+         * Pop.
+         * 
+         * @return the long
+         */
+        long pop() {
+            return values[--pos];
+        }
+
+        /**
+         * Checks if is empty.
+         * 
+         * @return true, if is empty
+         */
+        boolean isEmpty() {
+            return pos == 0;
+        }
+
+        /**
+         * Ensure.
+         * 
+         * @param size the size
+         */
+        private void ensure(int size) {
+            long[] arr = new long[Math.max(2 * values.length, size)];
+            System.arraycopy(values, 0, arr, 0, values.length);
+            values = arr;
+        }
+    }
+}
diff --git a/awt/javax/imageio/stream/ImageOutputStream.java b/awt/javax/imageio/stream/ImageOutputStream.java
new file mode 100644
index 0000000..e59b69d
--- /dev/null
+++ b/awt/javax/imageio/stream/ImageOutputStream.java
@@ -0,0 +1,270 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+package javax.imageio.stream;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * The ImageOutputStream represents output stream interface that is 
+ * used by ImageWriters.
+ */
+public interface ImageOutputStream extends DataOutput, ImageInputStream {
+
+    /**
+     * Writes a single byte to the stream at the current position. 
+     * 
+     * @param b the int value, of which the 8 lowest bits 
+     * will be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void write(int b) throws IOException;
+
+    /**
+     * Writes the bytes array to the stream.
+     * 
+     * @param b the byte array to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void write(byte[] b) throws IOException;
+
+    /**
+     * Writes a number of bytes from the specified byte array
+     * beggining from the specified offset.
+     * 
+     * @param b the byte array.
+     * @param off the offset.
+     * @param len the number of bytes to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void write(byte[] b, int off, int len) throws IOException;
+
+    /**
+     * Writes the specified boolean value to the stream, 1 if it is true,
+     * 0 if it is false.
+     * 
+     * @param b the boolean value to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeBoolean(boolean b) throws IOException;
+
+    /**
+     * Writes the 8 lowest bits of the specified int value to the stream. 
+     * 
+     * @param b the specified int value.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeByte(int b) throws IOException;
+
+    /**
+     * Writes a short value to the output stream. 
+     * 
+     * @param v the short value to be written. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeShort(int v) throws IOException;
+
+    /**
+     * Writes the 16 lowest bits of the specified int value to the stream.
+     * 
+     * @param v the specified int value.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeChar(int v) throws IOException;
+
+    /**
+     * Writes an integer value to the output stream. 
+     * 
+     * @param v the integer value to be written. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeInt(int v) throws IOException;
+
+    /**
+     * Write long.
+     * 
+     * @param v the long value
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeLong(long v) throws IOException;
+
+    /**
+     * Writes a float value to the output stream. 
+     * 
+     * @param v the float which contains value to be written. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeFloat(float v) throws IOException;
+
+    /**
+     * Writes a double value to the output stream. 
+     * 
+     * @param v the double which contains value to be written. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeDouble(double v) throws IOException;
+
+    /**
+     * Writes the specified string to the stream.
+     * 
+     * @param s the string to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeBytes(String s) throws IOException;
+
+    /**
+     * Writes the specified String to the output stream.
+     * 
+     * @param s the String to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeChars(String s) throws IOException;
+
+    /**
+     * Writes 2 bytes to the output stream in 
+     * the modified UTF-8  representation of every character of
+     * the specified string.      
+     * 
+     * @param s the specified string to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeUTF(String s) throws IOException;
+
+    /**
+     * Flushes the initial position in this stream prior to the
+     * specified stream position.
+     * 
+     * @param pos the position.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void flushBefore(long pos) throws IOException;
+
+
+    /**
+     * Writes a len number of short values from the specified array
+     * to the stream.
+     * 
+     * @param s the shorts array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeShorts(short[] s, int off, int len) throws IOException;
+
+    /**
+     * Writes a len number of chars to the stream.
+     * 
+     * @param c the char array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeChars(char[] c, int off, int len) throws IOException;
+
+    /**
+     * Writes a len number of int values from the specified array
+     * to the stream.
+     * 
+     * @param i the int array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeInts(int[] i, int off, int len) throws IOException;
+
+    /**
+     * Writes a len number of long values from the specified array
+     * to the stream.
+     * 
+     * @param l the long array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeLongs(long[] l, int off, int len) throws IOException;
+
+    /**
+     * Writes a len number of float values from the specified array
+     * to the stream.
+     * 
+     * @param f the float array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeFloats(float[] f, int off, int len) throws IOException;
+
+    /**
+     * Writes a len number of double values from the specified array
+     * to the stream.
+     * 
+     * @param d the double array to be written.
+     * @param off the offset in the char array.
+     * @param len the length of chars to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeDoubles(double[] d, int off, int len) throws IOException;
+
+    /**
+     * Writes a single bit at the current position.
+     * 
+     * @param bit the an int whose least significant bit is to be 
+     * written to the stream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeBit(int bit) throws IOException;
+
+    /**
+     * Writes a sequence of bits beggining from the current position.
+     * 
+     * @param bits a long value containing the bits to be written,
+     * starting with the bit in position numBits - 1 down to the 
+     * least significant bit.
+     * @param numBits the number of significant bit , 
+     * it can be between 0 and 64. 
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    void writeBits(long bits, int numBits) throws IOException;
+
+}
diff --git a/awt/javax/imageio/stream/ImageOutputStreamImpl.java b/awt/javax/imageio/stream/ImageOutputStreamImpl.java
new file mode 100644
index 0000000..c3d80fa
--- /dev/null
+++ b/awt/javax/imageio/stream/ImageOutputStreamImpl.java
@@ -0,0 +1,169 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  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.stream;
+
+import java.io.IOException;
+import java.nio.ByteOrder;
+
+/* 
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+
+/**
+ * The ImageOutputStreamImpl abstract class implements
+ * the ImageOutputStream interface.
+ */
+public abstract class ImageOutputStreamImpl extends ImageInputStreamImpl
+        implements ImageOutputStream {
+
+    /**
+     * Instantiates a new ImageOutputStreamImpl.
+     */
+    public ImageOutputStreamImpl() {}
+
+    public abstract void write(int b) throws IOException;
+
+    public void write(byte[] b) throws IOException {
+        write(b, 0, b.length);
+    }
+
+    public abstract void write(byte[] b, int off, int len) throws IOException;
+
+    public void writeBoolean(boolean v) throws IOException {
+        write(v ? 1 : 0);
+    }
+
+    public void writeByte(int v) throws IOException {
+        write(v);
+    }
+
+    public void writeShort(int v) throws IOException {
+        if (byteOrder == ByteOrder.BIG_ENDIAN) {
+
+        } else {
+
+        }
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeChar(int v) throws IOException {
+        writeShort(v);
+    }
+
+    public void writeInt(int v) throws IOException {
+        if (byteOrder == ByteOrder.BIG_ENDIAN) {
+
+        } else {
+
+        }
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeLong(long v) throws IOException {
+        if (byteOrder == ByteOrder.BIG_ENDIAN) {
+
+        } else {
+
+        }
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeFloat(float v) throws IOException {
+        writeInt(Float.floatToIntBits(v));
+    }
+
+    public void writeDouble(double v) throws IOException {
+        writeLong(Double.doubleToLongBits(v));
+    }
+
+    public void writeBytes(String s) throws IOException {
+        write(s.getBytes());
+    }
+
+    public void writeChars(String s) throws IOException {
+        char[] chs = s.toCharArray();
+        writeChars(chs, 0, chs.length);
+    }
+
+    public void writeUTF(String s) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeShorts(short[] s, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeChars(char[] c, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeInts(int[] i, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeLongs(long[] l, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeFloats(float[] f, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeDoubles(double[] d, int off, int len) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeBit(int bit) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    public void writeBits(long bits, int numBits) throws IOException {
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Flushes the bits. This method should be called in the write
+     * methods by subclasses.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    protected final void flushBits() throws IOException {
+        if (bitOffset == 0) {
+            return;
+        }
+        
+        //-- TODO implement
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+}
diff --git a/awt/javax/imageio/stream/MemoryCacheImageInputStream.java b/awt/javax/imageio/stream/MemoryCacheImageInputStream.java
new file mode 100644
index 0000000..a3d470b
--- /dev/null
+++ b/awt/javax/imageio/stream/MemoryCacheImageInputStream.java
@@ -0,0 +1,113 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.stream;
+
+import org.apache.harmony.x.imageio.stream.RandomAccessMemoryCache;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * The MemoryCacheImageInputStream class implements ImageInputStream
+ * using a memory buffer for caching the data.
+ */
+public class MemoryCacheImageInputStream  extends ImageInputStreamImpl {
+    
+    /** The is. */
+    private InputStream is;
+    
+    /** The ramc. */
+    private RandomAccessMemoryCache ramc = new RandomAccessMemoryCache();
+
+    /**
+     * Instantiates a new MemoryCacheImageInputStream
+     * which reads from the specified InputStream.
+     * 
+     * @param stream the InputStream to be read.
+     */
+    public MemoryCacheImageInputStream(InputStream stream) {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream == null!");
+        }
+        is = stream;
+    }
+
+    @Override
+    public int read() throws IOException {
+        bitOffset = 0;
+
+        if (streamPos >= ramc.length()) {
+            int count = (int)(streamPos - ramc.length() + 1);
+            int bytesAppended = ramc.appendData(is, count);
+
+            if (bytesAppended < count) {
+                return -1;
+            }
+        }
+
+        int res = ramc.getData(streamPos);
+        if (res >= 0) {
+            streamPos++;
+        }
+        return res;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        bitOffset = 0;
+
+        if (streamPos >= ramc.length()) {
+            int count = (int)(streamPos - ramc.length() + len);
+            ramc.appendData(is, count);
+        }
+
+        int res = ramc.getData(b, off, len, streamPos);
+        if (res > 0) {
+            streamPos += res;
+        }
+        return res;
+    }
+
+    @Override
+    public boolean isCached() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedFile() {
+        return false;
+    }
+
+    @Override
+    public boolean isCachedMemory() {
+        return true;
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+        ramc.close();
+    }
+
+    @Override
+    public void flushBefore(long pos) throws IOException {
+        super.flushBefore(pos);
+        ramc.freeBefore(getFlushedPosition());
+    }
+}
diff --git a/awt/javax/imageio/stream/MemoryCacheImageOutputStream.java b/awt/javax/imageio/stream/MemoryCacheImageOutputStream.java
new file mode 100644
index 0000000..96ded43
--- /dev/null
+++ b/awt/javax/imageio/stream/MemoryCacheImageOutputStream.java
@@ -0,0 +1,130 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+package javax.imageio.stream;
+
+import org.apache.harmony.x.imageio.stream.RandomAccessMemoryCache;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+
+/**
+ * The MemoryCacheImageOutputStream class implements ImageOutputStream
+ * using a memory buffer for caching the data.
+ */
+public class MemoryCacheImageOutputStream extends ImageOutputStreamImpl {
+    
+    /** The os. */
+    OutputStream os;
+    
+    /** The ramc. */
+    RandomAccessMemoryCache ramc = new RandomAccessMemoryCache();
+
+    /**
+     * Instantiates a new MemoryCacheImageOutputStream
+     * which writes to the specified OutputStream.
+     * 
+     * @param stream the OutputStream.
+     */
+    public MemoryCacheImageOutputStream(OutputStream stream) {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream == null!");
+        }
+        os = stream;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        flushBits(); // See the flushBits method description
+
+        ramc.putData(b, streamPos);
+        streamPos++;
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        flushBits(); // See the flushBits method description
+
+        ramc.putData(b, off, len, streamPos);
+        streamPos += len;
+    }
+
+    @Override
+    public int read() throws IOException {
+        bitOffset = 0;
+
+        int res = ramc.getData(streamPos);
+        if (res >= 0) {
+            streamPos++;
+        }
+        return res;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        bitOffset = 0;
+
+        int res = ramc.getData(b, off, len, streamPos);
+        if (res > 0) {
+            streamPos += res;
+        }
+        return res;
+    }
+
+    @Override
+    public long length() {
+        return ramc.length();
+    }
+
+    @Override
+    public boolean isCached() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedMemory() {
+        return true;
+    }
+
+    @Override
+    public boolean isCachedFile() {
+        return false;
+    }
+
+    @Override
+    public void close() throws IOException {
+        flushBefore(length());
+        super.close();
+        ramc.close();
+    }
+
+    @Override
+    public void flushBefore(long pos) throws IOException {
+        long flushedPosition = getFlushedPosition();
+        super.flushBefore(pos);
+
+        long newFlushedPosition = getFlushedPosition();
+        int nBytes = (int)(newFlushedPosition - flushedPosition);
+
+        ramc.getData(os, nBytes, flushedPosition);
+        ramc.freeBefore(newFlushedPosition);
+
+        os.flush();        
+    }
+}