diff --git a/awt/Android.mk b/awt/Android.mk
new file mode 100644
index 0000000..c7480f5
--- /dev/null
+++ b/awt/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
+LOCAL_JAVA_LIBRARIES := core framework
+
+LOCAL_MODULE:= android.awt
+
+LOCAL_DX_FLAGS := --core-library
+
+include $(BUILD_JAVA_LIBRARY)
diff --git a/awt/com/android/internal/awt/AndroidGraphics2D.java b/awt/com/android/internal/awt/AndroidGraphics2D.java
new file mode 100644
index 0000000..9a8ae02
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidGraphics2D.java
@@ -0,0 +1,1354 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed 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 com.android.internal.awt;
+
+import com.android.internal.awt.AndroidGraphicsConfiguration;
+import com.android.internal.graphics.NativeUtils;
+
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.PathIterator;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+import java.awt.image.renderable.RenderableImage;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.font.AndroidGlyphVector;
+import org.apache.harmony.awt.gl.font.FontMetricsImpl;
+import org.apache.harmony.awt.gl.image.OffscreenImage;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.graphics.Typeface;
+import android.graphics.PixelXorXfermode;
+import android.view.Display;
+import android.view.WindowManager;
+import android.content.Context;
+
+public class AndroidGraphics2D extends Graphics2D {
+    
+    private int displayWidth, displayHeight;
+
+    protected Surface dstSurf = null;
+    protected MultiRectArea clip = null;
+
+    protected Composite composite = AlphaComposite.SrcOver;
+    protected AffineTransform transform = new AffineTransform();
+
+    private static AndroidGraphics2D mAg;
+    private static Canvas mC;
+
+    // Android Paint
+    public static Paint mP;
+
+    private static java.awt.Font mFnt;
+
+    // Cached Matrix
+    public static Matrix mM;
+    private static FontMetrics mFm;
+    private static RenderingHints mRh;
+    private static Color mBc;
+
+    private Area mCurrClip;
+    
+    public final static double RAD_360 = Math.PI / 180 * 360;
+    
+    // Image drawing
+    private AndroidJavaBlitter blitter;
+    private DirectColorModel cm;
+    private SinglePixelPackedSampleModel sm;
+    private WritableRaster wr;
+
+
+    public static AndroidGraphics2D getInstance() {
+        if (mAg == null) {
+            throw new RuntimeException("AndroidGraphics2D not instantiated!");
+        }
+        return mAg;
+    }
+
+    public static AndroidGraphics2D getInstance(Context ctx, Canvas c, Paint p) {
+        if (c == null || ctx == null) {
+            throw new RuntimeException(
+                    "Illegal argument, Canvas cannot be null!");
+        }
+        mAg = new AndroidGraphics2D(ctx, c, p);
+        return mAg;
+    }
+
+    private AndroidGraphics2D(Context ctx, Canvas c, Paint p) {
+        super();
+        mC = c;
+        mP = p;
+        mM = new Matrix();
+        mM.reset();
+        mM = mC.getMatrix();
+        Rect r = mC.getClipBounds();
+        int cl[] = {-1, r.top, r.left, -2, r.top, r.right, -2, r.bottom, r.right, -2, r.bottom, r.left};
+        mCurrClip = new Area(createShape(cl));
+        if(ctx != null) {
+            WindowManager wm = (WindowManager)ctx.getSystemService(Context.WINDOW_SERVICE);
+            Display d = wm.getDefaultDisplay();
+            displayWidth = d.getWidth();
+            displayHeight = d.getHeight();
+        }
+        blitter = new AndroidJavaBlitter(c);
+        cm = new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
+        sm = new SinglePixelPackedSampleModel(
+                DataBuffer.TYPE_INT, displayWidth, displayHeight, cm.getMasks());
+        wr = Raster.createWritableRaster(sm, null);
+        dstSurf = new ImageSurface(cm, wr);       
+    }
+
+    @Override
+    public void addRenderingHints(Map<?, ?> hints) {
+        if (mRh == null) {
+            mRh = (RenderingHints) hints;
+        }
+        mRh.add((RenderingHints) hints);
+    }
+
+    public float[] getMatrix() {
+        float[] f = new float[9];
+        mC.getMatrix().getValues(f);
+        return f;
+    }
+
+    /**
+     * 
+     * @return a Matrix in Android format
+     */
+    public float[] getInverseMatrix() {
+        AffineTransform af = new AffineTransform(createAWTMatrix(getMatrix()));
+        try {
+            af = af.createInverse();
+        } catch (NoninvertibleTransformException e) {
+        }
+        return createMatrix(af);
+    }
+
+    private Path getPath(Shape s) {
+        Path path = new Path();
+        PathIterator pi = s.getPathIterator(null);
+        while (pi.isDone() == false) {
+            getCurrentSegment(pi, path);
+            pi.next();
+        }
+        return path;
+    }
+
+    private void getCurrentSegment(PathIterator pi, Path path) {
+        float[] coordinates = new float[6];
+        int type = pi.currentSegment(coordinates);
+        switch (type) {
+        case PathIterator.SEG_MOVETO:
+            path.moveTo(coordinates[0], coordinates[1]);
+            break;
+        case PathIterator.SEG_LINETO:
+            path.lineTo(coordinates[0], coordinates[1]);
+            break;
+        case PathIterator.SEG_QUADTO:
+            path.quadTo(coordinates[0], coordinates[1], coordinates[2],
+                    coordinates[3]);
+            break;
+        case PathIterator.SEG_CUBICTO:
+            path.cubicTo(coordinates[0], coordinates[1], coordinates[2],
+                    coordinates[3], coordinates[4], coordinates[5]);
+            break;
+        case PathIterator.SEG_CLOSE:
+            path.close();
+            break;
+        default:
+            break;
+        }
+    }
+    
+    private Shape createShape(int[] arr) {
+        Shape s = new GeneralPath();
+        for(int i = 0; i < arr.length; i++) {
+            int type = arr[i];    
+            switch (type) {
+            case -1:
+                //MOVETO
+                ((GeneralPath)s).moveTo(arr[++i], arr[++i]);
+                break;
+            case -2:
+                //LINETO
+                ((GeneralPath)s).lineTo(arr[++i], arr[++i]);
+                break;
+            case -3:
+                //QUADTO
+                ((GeneralPath)s).quadTo(arr[++i], arr[++i], arr[++i],
+                        arr[++i]);
+                break;
+            case -4:
+                //CUBICTO
+                ((GeneralPath)s).curveTo(arr[++i], arr[++i], arr[++i],
+                        arr[++i], arr[++i], arr[++i]);
+                break;
+            case -5:
+                //CLOSE
+                return s;
+            default:
+                break;
+            }
+        }
+        return s;
+    }
+    /*
+    public int[] getPixels() {
+        return mC.getPixels();
+    }*/
+
+    public static float getRadian(float degree) {
+        return (float) ((Math.PI / 180) * degree);
+    }
+    
+    private Shape getShape() {
+        return null;
+    }
+
+    public static float getDegree(float radian) {
+        return (float) ((180 / Math.PI) * radian);
+    }
+
+    /*
+     * Degree in radian
+     */
+    public static float getEllipsisX(float degree, float princAxis) {
+        return (float) Math.cos(degree) * princAxis;
+    }
+
+    public static float getEllipsisY(float degree, float conAxis) {
+        return (float) Math.sin(degree) * conAxis;
+    }
+
+    @Override
+    public void clip(Shape s) {
+        mC.clipPath(getPath(s));
+    }
+
+    public void setCanvas(Canvas c) {
+        mC = c;
+    }
+
+    @Override
+    public void draw(Shape s) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        Paint.Style tmp = mP.getStyle();
+        mP.setStyle(Paint.Style.STROKE);
+        mC.drawPath(getPath(s), mP);
+        mP.setStyle(tmp);
+    }
+/*
+    private ArrayList getSegments(Shape s) {
+        ArrayList arr = new ArrayList();
+        PathIterator pi = s.getPathIterator(null);
+        while (pi.isDone() == false) {
+            getCurrentSegment(pi, arr);
+            pi.next();
+        }
+        return arr;
+    }
+
+    private void getCurrentSegment(PathIterator pi, ArrayList arr) {
+        float[] coordinates = new float[6];
+        int type = pi.currentSegment(coordinates);
+        switch (type) {
+        case PathIterator.SEG_MOVETO:
+            arr.add(new Integer(-1));
+            break;
+        case PathIterator.SEG_LINETO:
+            arr.add(new Integer(-2));
+            break;
+        case PathIterator.SEG_QUADTO:
+            arr.add(new Integer(-3));
+            break;
+        case PathIterator.SEG_CUBICTO:
+            arr.add(new Integer(-4));
+            break;
+        case PathIterator.SEG_CLOSE:
+            arr.add(new Integer(-5));
+            break;
+        default:
+            break;
+        }
+    }
+*/
+    /*
+     * Convenience method, not standard AWT
+     */
+    public void draw(Path s) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        Paint.Style tmp = mP.getStyle();
+        mP.setStyle(Paint.Style.STROKE);
+        s.transform(mM);
+        mC.drawPath(s, mP);
+        mP.setStyle(tmp);
+    }
+
+    @Override
+    public void drawGlyphVector(GlyphVector g, float x, float y) {
+        // TODO draw at x, y
+        // draw(g.getOutline());
+        /*
+        Matrix matrix = new Matrix();
+        matrix.setTranslate(x, y);
+        Path pth = getPath(g.getOutline());
+        pth.transform(matrix);
+        draw(pth);
+        */
+        Path path = new Path();
+        char[] c = ((AndroidGlyphVector)g).getGlyphs();
+        mP.getTextPath(c, 0, c.length, x, y, path);
+        mC.drawPath(path, mP);
+    }
+
+    @Override
+    public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
+        throw new RuntimeException("Not implemented!");
+    }
+
+    @Override
+    public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
+        throw new RuntimeException("Not implemented!");
+    }
+
+    @Override
+    public void drawString(AttributedCharacterIterator iterator, float x,
+            float y) {
+        throw new RuntimeException("AttributedCharacterIterator not supported!");
+
+    }
+
+    @Override
+    public void drawString(AttributedCharacterIterator iterator, int x, int y) {
+        throw new RuntimeException("AttributedCharacterIterator not supported!");
+
+    }
+
+    @Override
+    public void drawString(String s, float x, float y) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+
+            mP.setStyle(Paint.Style.FILL);
+            Path pth = new Path();
+            mP.getTextPath(s, 0, s.length(), x, y, pth);
+            mC.drawPath(pth, mP);
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public void drawString(String str, int x, int y) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+            mP.setStrokeWidth(0);
+
+            mC.drawText(str.toCharArray(), 0, str.toCharArray().length, x, y,
+                    mP);
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public void fill(Shape s) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+            mP.setStyle(Paint.Style.FILL);
+            mC.drawPath(getPath(s), mP);
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public Color getBackground() {
+        return mBc;
+    }
+
+    @Override
+    public Composite getComposite() {
+        throw new RuntimeException("Composite not implemented!");
+    }
+
+    @Override
+    public GraphicsConfiguration getDeviceConfiguration() {
+        return new AndroidGraphicsConfiguration();
+    }
+
+    @Override
+    public FontRenderContext getFontRenderContext() {
+        return new FontRenderContext(getTransform(), mP.isAntiAlias(), true);
+    }
+
+    @Override
+    public java.awt.Paint getPaint() {
+        throw new RuntimeException("AWT Paint not implemented in Android!");
+    }
+
+    public static Canvas getAndroidCanvas() {
+        return mC;
+    }
+    
+    public static Paint getAndroidPaint() {
+        return mP;
+    }
+
+    @Override
+    public RenderingHints getRenderingHints() {
+        return mRh;
+    }
+
+    @Override
+    public Stroke getStroke() {
+        if (mP != null) {
+            return new BasicStroke(mP.getStrokeWidth(), mP.getStrokeCap()
+                    .ordinal(), mP.getStrokeJoin().ordinal());
+        }
+        return null;
+    }
+
+    @Override
+    public AffineTransform getTransform() {
+        return new AffineTransform(createAWTMatrix(getMatrix()));
+    }
+
+    @Override
+    public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
+        // ???AWT TODO check if on stroke
+        return s.intersects(rect.getX(), rect.getY(), rect.getWidth(), rect
+                .getHeight());
+    }
+
+    @Override
+    public void rotate(double theta) {
+        mM.preRotate((float) AndroidGraphics2D
+                .getDegree((float) (RAD_360 - theta)));
+        mC.concat(mM);
+    }
+
+    @Override
+    public void rotate(double theta, double x, double y) {
+        mM.preRotate((float) AndroidGraphics2D.getDegree((float) theta),
+                (float) x, (float) y);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void scale(double sx, double sy) {
+        mM.setScale((float) sx, (float) sy);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void setBackground(Color color) {
+        mBc = color;
+        mC.clipRect(new Rect(0, 0, mC.getWidth(), mC.getHeight()));
+        // TODO don't limit to current clip
+        mC.drawARGB(color.getAlpha(), color.getRed(), color.getGreen(), color
+                .getBlue());
+    }
+
+    @Override
+    public void setComposite(Composite comp) {
+        throw new RuntimeException("Composite not implemented!");
+    }
+
+    public void setSpaint(Paint paint) {
+        mP = paint;
+    }
+
+    @Override
+    public void setPaint(java.awt.Paint paint) {
+        setColor((Color)paint);
+    }
+
+    @Override
+    public Object getRenderingHint(RenderingHints.Key key) {
+        if (mRh == null) {
+            return null;
+        }
+        return mRh.get(key);
+    }
+
+    @Override
+    public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) {
+        if (mRh == null) {
+            mRh = new RenderingHints(hintKey, hintValue);
+        } else {
+            mRh.put(hintKey, hintValue);
+        }
+        applyHints();
+    }
+
+    @Override
+    public void setRenderingHints(Map<?, ?> hints) {
+        mRh = (RenderingHints) hints;
+        applyHints();
+    }
+
+    private void applyHints() {
+        Object o;
+
+        // TODO do something like this:
+        /*
+         * Set s = mRh.keySet(); Iterator it = s.iterator(); while(it.hasNext()) {
+         * o = it.next(); }
+         */
+
+        // /////////////////////////////////////////////////////////////////////
+        // not supported in skia
+        /*
+         * o = mRh.get(RenderingHints.KEY_ALPHA_INTERPOLATION); if
+         * (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) { } else
+         * if (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) { }
+         * else if (o.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_COLOR_RENDERING); if
+         * (o.equals(RenderingHints.VALUE_COLOR_RENDER_DEFAULT)) { } else if
+         * (o.equals(RenderingHints.VALUE_COLOR_RENDER_QUALITY)) { } else if
+         * (o.equals(RenderingHints.VALUE_COLOR_RENDER_SPEED)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_DITHERING); if
+         * (o.equals(RenderingHints.VALUE_DITHER_DEFAULT)) { } else if
+         * (o.equals(RenderingHints.VALUE_DITHER_DISABLE)) { } else if
+         * (o.equals(RenderingHints.VALUE_DITHER_ENABLE)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_FRACTIONALMETRICS); if
+         * (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT)) { } else
+         * if (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_OFF)) { } else if
+         * (o.equals(RenderingHints.VALUE_FRACTIONALMETRICS_ON)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_INTERPOLATION); if
+         * (o.equals(RenderingHints.VALUE_INTERPOLATION_BICUBIC)) { } else if
+         * (o.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) { } else if
+         * (o .equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_RENDERING); if
+         * (o.equals(RenderingHints.VALUE_RENDER_DEFAULT)) { } else if
+         * (o.equals(RenderingHints.VALUE_RENDER_QUALITY)) { } else if
+         * (o.equals(RenderingHints.VALUE_RENDER_SPEED)) { }
+         * 
+         * o = mRh.get(RenderingHints.KEY_STROKE_CONTROL); if
+         * (o.equals(RenderingHints.VALUE_STROKE_DEFAULT)) { } else if
+         * (o.equals(RenderingHints.VALUE_STROKE_NORMALIZE)) { } else if
+         * (o.equals(RenderingHints.VALUE_STROKE_PURE)) { }
+         */
+
+        o = mRh.get(RenderingHints.KEY_ANTIALIASING);
+        if (o != null) {
+            if (o.equals(RenderingHints.VALUE_ANTIALIAS_DEFAULT)) {
+                mP.setAntiAlias(false);
+            } else if (o.equals(RenderingHints.VALUE_ANTIALIAS_OFF)) {
+                mP.setAntiAlias(false);
+            } else if (o.equals(RenderingHints.VALUE_ANTIALIAS_ON)) {
+                mP.setAntiAlias(true);
+            }
+        }
+
+        o = mRh.get(RenderingHints.KEY_TEXT_ANTIALIASING);
+        if (o != null) {
+            if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT)) {
+                mP.setAntiAlias(false);
+            } else if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)) {
+                mP.setAntiAlias(false);
+            } else if (o.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_ON)) {
+                mP.setAntiAlias(true);
+            }
+        }
+    }
+
+    @Override
+    public void setStroke(Stroke s) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        BasicStroke bs = (BasicStroke) s;
+        mP.setStyle(Paint.Style.STROKE);
+        mP.setStrokeWidth(bs.getLineWidth());
+
+        int cap = bs.getEndCap();
+        if (cap == 0) {
+            mP.setStrokeCap(Paint.Cap.BUTT);
+        } else if (cap == 1) {
+            mP.setStrokeCap(Paint.Cap.ROUND);
+        } else if (cap == 2) {
+            mP.setStrokeCap(Paint.Cap.SQUARE);
+        }
+
+        int join = bs.getLineJoin();
+        if (join == 0) {
+            mP.setStrokeJoin(Paint.Join.MITER);
+        } else if (join == 1) {
+            mP.setStrokeJoin(Paint.Join.ROUND);
+        } else if (join == 2) {
+            mP.setStrokeJoin(Paint.Join.BEVEL);
+        }
+    }
+
+    public static float[] createMatrix(AffineTransform Tx) {
+        double[] at = new double[9];
+        Tx.getMatrix(at);
+        float[] f = new float[at.length];
+        f[0] = (float) at[0];
+        f[1] = (float) at[2];
+        f[2] = (float) at[4];
+        f[3] = (float) at[1];
+        f[4] = (float) at[3];
+        f[5] = (float) at[5];
+        f[6] = 0;
+        f[7] = 0;
+        f[8] = 1;
+        return f;
+    }
+
+    private float[] createAWTMatrix(float[] matrix) {
+        float[] at = new float[9];
+        at[0] = matrix[0];
+        at[1] = matrix[3];
+        at[2] = matrix[1];
+        at[3] = matrix[4];
+        at[4] = matrix[2];
+        at[5] = matrix[5];
+        at[6] = 0;
+        at[7] = 0;
+        at[8] = 1;
+        return at;
+    }
+
+    public static Matrix createMatrixObj(AffineTransform Tx) {
+        Matrix m = new Matrix();
+        m.reset();
+        m.setValues(createMatrix(Tx));
+        return m;
+    }
+
+    @Override
+    public void setTransform(AffineTransform Tx) {
+        mM.reset();
+        /*
+         * if(Tx.isIdentity()) { mM = new Matrix(); }
+         */
+        mM.setValues(createMatrix(Tx));
+        Matrix m = new Matrix();
+        m.setValues(getInverseMatrix());
+        mC.concat(m);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void shear(double shx, double shy) {
+        mM.setSkew((float) shx, (float) shy);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void transform(AffineTransform Tx) {
+        Matrix m = new Matrix();
+        m.setValues(createMatrix(Tx));
+        mC.concat(m);
+    }
+
+    @Override
+    public void translate(double tx, double ty) {
+        mM.setTranslate((float) tx, (float) ty);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void translate(int x, int y) {
+        mM.setTranslate((float) x, (float) y);
+        mC.concat(mM);
+    }
+
+    @Override
+    public void clearRect(int x, int y, int width, int height) {
+        mC.clipRect(x, y, x + width, y + height);
+        if (mBc != null) {
+            mC.drawARGB(mBc.getAlpha(), mBc.getBlue(), mBc.getGreen(), mBc
+                    .getRed());
+        } else {
+            mC.drawARGB(0xff, 0xff, 0xff, 0xff);
+        }
+    }
+
+    @Override
+    public void clipRect(int x, int y, int width, int height) {
+        int cl[] = {-1, x, y, -2, x, y + width, -2, x + height, y + width, -2, x + height, y};
+        Shape shp = createShape(cl);
+        mCurrClip.intersect(new Area(shp));
+        mC.clipRect(new Rect(x, y, x + width, y + height), Region.Op.INTERSECT);
+    }
+
+    @Override
+    public void copyArea(int sx, int sy, int width, int height, int dx, int dy) {
+        copyArea(mC, sx, sy, width + dx, height + dy, dx, dy);
+    }
+
+    @Override
+    public Graphics create() {
+        return this;
+    }
+
+    @Override
+    public void dispose() {
+            mC = null;
+            mP = null;
+    }
+
+    @Override
+    public void drawArc(int x, int y, int width, int height, int sa, int ea) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            mP.setStrokeWidth(0);
+            mC.drawArc(new RectF(x, y, x + width, y + height), 360 - (ea + sa),
+                       ea, true, mP);
+    }
+
+    
+    // ???AWT: only used for debuging, delete in final version
+    public void drawBitmap(Bitmap bm, float x, float y, Paint p) {
+        mC.drawBitmap(bm, x, y, null);
+    }
+    
+    @Override
+    public boolean drawImage(Image image, int x, int y, Color bgcolor,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, (AffineTransform) transform.clone(),
+                    composite, bgcolor, clip);
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, ImageObserver imageObserver) {
+        return drawImage(image, x, y, null, imageObserver);
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, int width, int height,
+            Color bgcolor, ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(width == 0 || height == 0) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            if(w == width && h == height){
+                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                        (AffineTransform) transform.clone(),
+                        composite, bgcolor, clip);
+            }else{
+                AffineTransform xform = new AffineTransform();
+                xform.setToScale((float)width / w, (float)height / h);
+                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                        (AffineTransform) transform.clone(),
+                        xform, composite, bgcolor, clip);
+            }
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, int width, int height,
+            ImageObserver imageObserver) {
+        return drawImage(image, x, y, width, height, null, imageObserver);
+    }
+
+    @Override
+    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
+            int sx1, int sy1, int sx2, int sy2, Color bgcolor,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(dx1 == dx2 || dy1 == dy2 || sx1 == sx2 || sy1 == sy2) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+
+            int dstX = dx1;
+            int dstY = dy1;
+            int srcX = sx1;
+            int srcY = sy1;
+
+            int dstW = dx2 - dx1;
+            int dstH = dy2 - dy1;
+            int srcW = sx2 - sx1;
+            int srcH = sy2 - sy1;
+
+            if(srcW == dstW && srcH == dstH){
+                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
+                        (AffineTransform) transform.clone(),
+                        composite, bgcolor, clip);
+            }else{
+                AffineTransform xform = new AffineTransform();
+                xform.setToScale((float)dstW / srcW, (float)dstH / srcH);
+                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
+                        (AffineTransform) transform.clone(),
+                        xform, composite, bgcolor, clip);
+            }
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
+            int sx1, int sy1, int sx2, int sy2, ImageObserver imageObserver) {
+
+        return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
+                imageObserver);
+     }
+
+    @Override
+    public void drawImage(BufferedImage bufImage, BufferedImageOp op,
+            int x, int y) {
+
+        if(bufImage == null) {
+            return;
+        }
+
+        if(op == null) {
+            drawImage(bufImage, x, y, null);
+        } else if(op instanceof AffineTransformOp){
+            AffineTransformOp atop = (AffineTransformOp) op;
+            AffineTransform xform = atop.getTransform();
+            Surface srcSurf = Surface.getImageSurface(bufImage);
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                    (AffineTransform) transform.clone(), xform,
+                    composite, null, clip);
+        } else {
+            bufImage = op.filter(bufImage, null);
+            Surface srcSurf = Surface.getImageSurface(bufImage);
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                    (AffineTransform) transform.clone(),
+                    composite, null, clip);
+        }
+    }
+
+    @Override
+    public boolean drawImage(Image image, AffineTransform trans,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(trans == null || trans.isIdentity()) {
+            return drawImage(image, 0, 0, imageObserver);
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            AffineTransform xform = (AffineTransform) transform.clone();
+            xform.concatenate(trans);
+            blitter.blit(0, 0, srcSurf, 0, 0, dstSurf, w, h, xform, composite,
+                    null, clip);
+        }
+        return done;
+    }
+        
+    @Override
+    public void drawLine(int x1, int y1, int x2, int y2) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+            mC.drawLine(x1, y1, x2, y2, mP);
+    }
+
+    @Override
+    public void drawOval(int x, int y, int width, int height) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            mP.setStyle(Paint.Style.STROKE);
+            mC.drawOval(new RectF(x, y, x + width, y + height), mP);
+    }
+
+    @Override
+    public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            mC.drawLine(xpoints[npoints - 1], ypoints[npoints - 1], xpoints[0],
+                    ypoints[0], mP);
+            for (int i = 0; i < npoints - 1; i++) {
+                mC.drawLine(xpoints[i], ypoints[i], xpoints[i + 1],
+                        ypoints[i + 1], mP);
+            }
+    }
+
+    @Override
+    public void drawPolyline(int[] xpoints, int[] ypoints, int npoints) {
+        for (int i = 0; i < npoints - 1; i++) {
+            drawLine(xpoints[i], ypoints[i], xpoints[i + 1], ypoints[i + 1]);
+        }
+
+    }
+
+    @Override
+    public void drawRoundRect(int x, int y, int width, int height,
+            int arcWidth, int arcHeight) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            mC.drawRoundRect(new RectF(x, y, width, height), arcWidth,
+                    arcHeight, mP);
+    }
+
+    @Override
+    public void fillArc(int x, int y, int width, int height, int sa, int ea) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            
+            Paint.Style tmp = mP.getStyle();
+            mP.setStyle(Paint.Style.FILL_AND_STROKE);
+            mC.drawArc(new RectF(x, y, x + width, y + height), 360 - (sa + ea),
+                    ea, true, mP);
+            
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public void fillOval(int x, int y, int width, int height) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+            mP.setStyle(Paint.Style.FILL);
+            mC.drawOval(new RectF(x, y, x + width, y + height), mP);
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public void fillPolygon(int[] xpoints, int[] ypoints, int npoints) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+            mC.save(Canvas.CLIP_SAVE_FLAG);
+
+            mP.setStyle(Paint.Style.FILL);
+
+            GeneralPath filledPolygon = new GeneralPath(
+                    GeneralPath.WIND_EVEN_ODD, npoints);
+            filledPolygon.moveTo(xpoints[0], ypoints[0]);
+            for (int index = 1; index < xpoints.length; index++) {
+                filledPolygon.lineTo(xpoints[index], ypoints[index]);
+            }
+            filledPolygon.closePath();
+            Path path = getPath(filledPolygon);
+            mC.clipPath(path);
+            mC.drawPath(path, mP);
+
+            mP.setStyle(tmp);
+            mC.restore();
+    }
+
+    @Override
+    public void fillRect(int x, int y, int width, int height) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            Paint.Style tmp = mP.getStyle();
+            mP.setStyle(Paint.Style.FILL);
+            mC.drawRect(new Rect(x, y, x + width, y + height), mP);
+            mP.setStyle(tmp);
+    }
+
+    @Override
+    public void drawRect(int x, int y, int width, int height) {
+        int[] xpoints = { x, x, x + width, x + width };
+        int[] ypoints = { y, y + height, y + height, y };
+        drawPolygon(xpoints, ypoints, 4);
+    }
+
+    @Override
+    public void fillRoundRect(int x, int y, int width, int height,
+            int arcWidth, int arcHeight) {
+            if (mP == null) {
+                mP = new Paint();
+            }
+            mP.setStyle(Paint.Style.FILL);
+            mC.drawRoundRect(new RectF(x, y, x + width, y + height), arcWidth,
+                    arcHeight, mP);
+    }
+
+    @Override
+    public Shape getClip() {
+        return mCurrClip;
+    }
+
+    @Override
+    public Rectangle getClipBounds() {
+            Rect r = mC.getClipBounds();
+            return new Rectangle(r.left, r.top, r.width(), r.height());
+    }
+
+    @Override
+    public Color getColor() {
+        if (mP != null) {
+            return new Color(mP.getColor());
+        }
+        return null;
+    }
+
+    @Override
+    public Font getFont() {
+        return mFnt;
+    }
+
+    @Override
+    public FontMetrics getFontMetrics(Font font) {
+        mFm = new FontMetricsImpl(font);
+        return mFm;
+    }
+
+    @Override
+    public void setClip(int x, int y, int width, int height) {
+        int cl[] = {-1, x, y, -2, x, y + width, -2, x + height, y + width, -2, x + height, y};
+        mCurrClip = new Area(createShape(cl));
+        mC.clipRect(x, y, x + width, y + height, Region.Op.REPLACE);
+
+    }
+
+    @Override
+    public void setClip(Shape clip) {
+        mCurrClip = new Area(clip);
+        mC.clipPath(getPath(clip), Region.Op.REPLACE);
+    }
+
+    @Override
+    public void setColor(Color c) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        mP.setColor(c.getRGB());
+    }
+
+    /**
+     * Font mapping:
+     * 
+     * Family:
+     * 
+     * Android         AWT
+     * -------------------------------------
+     * serif           Serif / TimesRoman
+     * sans-serif      SansSerif / Helvetica
+     * monospace       Monospaced / Courier
+     * 
+     * Style:
+     * 
+     * Android            AWT
+     * -------------------------------------
+     * normal          Plain
+     * bold            bold
+     * italic          italic
+     * 
+     */
+    @Override
+    public void setFont(Font font) {
+        if (font == null) {
+            return;
+        }
+        if (mP == null) {
+            mP = new Paint();
+        }
+
+        mFnt = font;
+        Typeface tf = null;
+        int sty = font.getStyle();
+        String nam = font.getName();
+        String aF = "";
+        if (nam != null) {
+            if (nam.equalsIgnoreCase("Serif")
+                    || nam.equalsIgnoreCase("TimesRoman")) {
+                aF = "serif";
+            } else if (nam.equalsIgnoreCase("SansSerif")
+                    || nam.equalsIgnoreCase("Helvetica")) {
+                aF = "sans-serif";
+            } else if (nam.equalsIgnoreCase("Monospaced")
+                    || nam.equalsIgnoreCase("Courier")) {
+                aF = "monospace";
+            }
+        }
+
+        switch (sty) {
+        case Font.PLAIN:
+            tf = Typeface.create(aF, Typeface.NORMAL);
+            break;
+        case Font.BOLD:
+            tf = Typeface.create(aF, Typeface.BOLD);
+            break;
+        case Font.ITALIC:
+            tf = Typeface.create(aF, Typeface.ITALIC);
+            break;
+        case Font.BOLD | Font.ITALIC:
+            tf = Typeface.create(aF, Typeface.BOLD_ITALIC);
+            break;
+        default:
+            tf = Typeface.DEFAULT;
+        }
+
+        mP.setTextSize(font.getSize());
+        mP.setTypeface(tf);
+    }
+
+    @Override
+    public void drawBytes(byte[] data, int offset, int length, int x, int y) {
+        drawString(new String(data, offset, length), x, y);
+    }
+    
+    @Override
+    public void drawPolygon(Polygon p) {
+        drawPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+
+    @Override
+    public void fillPolygon(Polygon p) {
+        fillPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+    
+    @Override
+    public Rectangle getClipBounds(Rectangle r) {
+        Shape clip = getClip();
+        if (clip != null) {
+            Rectangle b = clip.getBounds();
+            r.x = b.x;
+            r.y = b.y;
+            r.width = b.width;
+            r.height = b.height;
+        }
+        return r;
+    }
+    
+    @Override
+    public boolean hitClip(int x, int y, int width, int height) {
+        return getClipBounds().intersects(new Rectangle(x, y, width, height));
+    }
+    
+    @Override
+    public void drawChars(char[] data, int offset, int length, int x, int y) {
+        mC.drawText(data, offset, length, x, y, mP);
+    }
+    
+    @Override
+    public void setPaintMode() {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        mP.setXfermode(null);
+    }
+
+    @Override
+    public void setXORMode(Color color) {
+        if (mP == null) {
+            mP = new Paint();
+        }
+        mP.setXfermode(new PixelXorXfermode(color.getRGB()));
+    }
+    
+    @Override
+    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+            setColor(color);
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+            setColor(colorUp);
+        }
+
+        width--;
+        height--;
+        fillRect(x+1, y+1, width-1, height-1);
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y+1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x+width, y, 1, height);
+        fillRect(x+1, y+height, width, 1);
+    }
+    
+    @Override
+    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+        }
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y+1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x+width, y, 1, height);
+        fillRect(x+1, y+height, width, 1);
+    }
+
+    public void copyArea(Canvas canvas, int sx, int sy, int width, int height, int dx, int dy) {
+        sx += getTransform().getTranslateX();
+        sy += getTransform().getTranslateY();
+
+        NativeUtils.nativeScrollRect(canvas,
+                new Rect(sx, sy, sx + width, sy + height),
+                dx, dy);
+    }
+}
diff --git a/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java b/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java
new file mode 100644
index 0000000..0c888cd
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed 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 com.android.internal.awt;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.VolatileImage;
+
+import android.graphics.Canvas;
+
+public class AndroidGraphicsConfiguration extends GraphicsConfiguration {
+
+    @Override
+    public BufferedImage createCompatibleImage(int width, int height) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public BufferedImage createCompatibleImage(int width, int height,
+            int transparency) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public VolatileImage createCompatibleVolatileImage(int width, int height) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public VolatileImage createCompatibleVolatileImage(int width, int height,
+            int transparency) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Rectangle getBounds() {
+        Canvas c = AndroidGraphics2D.getAndroidCanvas();
+        if(c != null)
+            return new Rectangle(0, 0, c.getWidth(), c.getHeight());
+        return null;
+    }
+
+    @Override
+    public ColorModel getColorModel() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ColorModel getColorModel(int transparency) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public AffineTransform getDefaultTransform() {
+        return new AffineTransform();
+    }
+
+    @Override
+    public GraphicsDevice getDevice() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public AffineTransform getNormalizingTransform() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
diff --git a/awt/com/android/internal/awt/AndroidGraphicsFactory.java b/awt/com/android/internal/awt/AndroidGraphicsFactory.java
new file mode 100644
index 0000000..ca255b5
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidGraphicsFactory.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed 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 com.android.internal.awt;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.peer.FontPeer;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.font.AndroidFont;
+import org.apache.harmony.awt.gl.font.FontManager;
+import org.apache.harmony.awt.gl.font.FontMetricsImpl;
+import org.apache.harmony.awt.gl.font.AndroidFontManager;
+import org.apache.harmony.awt.wtk.NativeWindow;
+import org.apache.harmony.awt.wtk.WindowFactory;
+import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.content.Context;
+
+public class AndroidGraphicsFactory extends CommonGraphics2DFactory {
+    
+    public GraphicsEnvironment createGraphicsEnvironment(WindowFactory wf) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Font embedFont(String fontFilePath) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public FontManager getFontManager() {
+        return AndroidFontManager.inst;
+    }
+
+    public FontMetrics getFontMetrics(Font font) {
+        return new FontMetricsImpl(font);
+    }
+
+    public FontPeer getFontPeer(Font font) {
+        //return getFontManager().getFontPeer(font.getName(), font.getStyle(), font.getSize());
+        return new AndroidFont(font.getName(), font.getStyle(), font.getSize());
+    }
+
+    public Graphics2D getGraphics2D(NativeWindow win, int translateX,
+            int translateY, MultiRectArea clip) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Graphics2D getGraphics2D(NativeWindow win, int translateX,
+            int translateY, int width, int height) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Graphics2D getGraphics2D(Context ctx, Canvas c, Paint p) {
+        return AndroidGraphics2D.getInstance(ctx, c, p);
+    }
+
+    public Graphics2D getGraphics2D(Canvas c, Paint p) {
+        throw new RuntimeException("Not supported!");
+    }
+
+    public Graphics2D getGraphics2D() {
+        return AndroidGraphics2D.getInstance();
+    }
+
+}
diff --git a/awt/com/android/internal/awt/AndroidImageDecoder.java b/awt/com/android/internal/awt/AndroidImageDecoder.java
new file mode 100644
index 0000000..81b2e1a
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidImageDecoder.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed 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 com.android.internal.awt;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+//import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.IndexColorModel;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.gl.image.DecodingImageSource;
+import org.apache.harmony.awt.gl.image.ImageDecoder;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class AndroidImageDecoder extends ImageDecoder {
+    
+    private static final int hintflags =
+        ImageConsumer.SINGLEFRAME | // PNG is a static image
+        ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
+        ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
+    
+    // Each pixel is a grayscale sample.
+    private static final int PNG_COLOR_TYPE_GRAY = 0;
+    // Each pixel is an R,G,B triple.
+    private static final int PNG_COLOR_TYPE_RGB = 2;
+    // Each pixel is a palette index, a PLTE chunk must appear.
+    private static final int PNG_COLOR_TYPE_PLTE = 3;
+    // Each pixel is a grayscale sample, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
+    // Each pixel is an R,G,B triple, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_RGBA = 6;
+    
+    private static final int NB_OF_LINES_PER_CHUNK = 1;  // 0 = full image
+    
+    Bitmap bm;  // The image as decoded by Android
+    
+    // Header information
+    int imageWidth; // Image size
+    int imageHeight;  
+    int colorType;  // One of the PNG_ constants from above
+    int bitDepth;   // Number of bits per color
+    byte cmap[];    // The color palette for index color models
+    ColorModel model;  // The corresponding AWT color model
+    
+    boolean transferInts; // Is transfer of type int or byte?
+    int dataElementsPerPixel;
+
+    // Buffers for decoded image data
+    byte byteOut[];
+    int intOut[];
+
+    
+    public AndroidImageDecoder(DecodingImageSource src, InputStream is) {
+        super(src, is);
+        dataElementsPerPixel = 1;
+    }
+
+    @Override
+    /**
+     * All the decoding is done in Android
+     * 
+     * AWT???: Method returns only once the image is completly 
+     * decoded; decoding is not done asynchronously
+     */
+    public void decodeImage() throws IOException {
+        try {
+            bm = BitmapFactory.decodeStream(inputStream);
+            if (bm == null) {
+                throw new IOException("Input stream empty and no image cached");
+            }
+
+            // Check size
+            imageWidth = bm.getWidth();
+            imageHeight = bm.getHeight();
+            if (imageWidth < 0 || imageHeight < 0 ) {
+                throw new RuntimeException("Illegal image size: " 
+                        + imageWidth + ", " + imageHeight);
+            }
+            
+            // We got the image fully decoded; now send all image data to AWT
+            setDimensions(imageWidth, imageHeight);
+            model = createColorModel();
+            setColorModel(model);
+            setHints(hintflags);
+            setProperties(new Hashtable<Object, Object>()); // Empty
+            sendPixels(NB_OF_LINES_PER_CHUNK != 0 ? NB_OF_LINES_PER_CHUNK : imageHeight);
+            imageComplete(ImageConsumer.STATICIMAGEDONE);        
+        } catch (IOException e) {
+            throw e;
+        } catch (RuntimeException e) {
+            imageComplete(ImageConsumer.IMAGEERROR);
+            throw e;
+        } finally {
+            closeStream();
+        }
+    }
+    
+    /**
+     * Create the AWT color model
+     *
+     * ???AWT: Android Bitmaps are always of type: ARGB-8888-Direct color model
+     * 
+     * However, we leave the code here for a more powerfull decoder 
+     * that returns a native model, and the conversion is then handled
+     * in AWT. With such a decoder, we would need to get the colorType, 
+     * the bitDepth, (and the color palette for an index color model)
+     * from the image and construct the correct color model here.
+     */
+    private ColorModel createColorModel() {
+        ColorModel cm = null;
+        int bmModel = 5; // TODO This doesn't exist: bm.getColorModel();
+        cmap = null;
+           
+        switch (bmModel) {
+        // A1_MODEL
+        case 1: 
+            colorType = PNG_COLOR_TYPE_GRAY;
+            bitDepth = 1;
+            break;
+            
+        // A8_MODEL
+        case 2:
+            colorType = PNG_COLOR_TYPE_GRAY_ALPHA;
+            bitDepth = 8;
+            break;
+            
+        // INDEX8_MODEL
+        // RGB_565_MODEL
+        // ARGB_8888_MODEL
+        case 3:
+        case 4: 
+        case 5: 
+            colorType = bm.hasAlpha() ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB;
+            bitDepth = 8;
+            break;
+
+        default:
+            // awt.3C=Unknown PNG color type
+            throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+        }
+        
+        switch (colorType) {
+        
+            case PNG_COLOR_TYPE_GRAY: {
+                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 &&  bitDepth != 1) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                // Create gray color model
+                int numEntries = 1 << bitDepth;
+                int scaleFactor = 255 / (numEntries-1);
+                byte comps[] = new byte[numEntries];
+                for (int i = 0; i < numEntries; i++) {
+                    comps[i] = (byte) (i * scaleFactor);
+                }
+                cm = new IndexColorModel(bitDepth, numEntries, comps, comps, comps);
+
+                transferInts = false;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_RGB: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+                
+                cm = new DirectColorModel(24, 0xff0000, 0xFF00, 0xFF);
+                
+                transferInts = true;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_PLTE: {
+                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                if (cmap == null) {
+                    throw new IllegalStateException("Palette color type is not supported");
+                }
+
+                cm = new IndexColorModel(bitDepth, cmap.length / 3, cmap, 0, false);
+
+                transferInts = false;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_GRAY_ALPHA: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                        true, false,
+                        Transparency.TRANSLUCENT,
+                        DataBuffer.TYPE_BYTE);
+
+                transferInts = false;
+                dataElementsPerPixel = 2;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_RGBA: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = ColorModel.getRGBdefault();
+
+                transferInts = true;
+                break;
+            }
+            default:
+                // awt.3C=Unknown PNG color type
+                throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+        }
+        
+        return cm;
+    }
+    
+    private void sendPixels(int nbOfLinesPerChunk) {
+        int w = imageWidth;
+        int h = imageHeight;
+        int n = 1;
+        if (nbOfLinesPerChunk > 0 && nbOfLinesPerChunk <= h) {
+            n = nbOfLinesPerChunk;
+        }
+        
+        if (transferInts) {
+            // Create output buffer
+            intOut = new int[w * n];
+            for (int yi = 0; yi < h; yi += n) {
+                // Last chunk might contain less liness
+                if (n > 1 && h - yi < n ) {
+                    n = h - yi;
+                }
+                bm.getPixels(intOut, 0, w, 0, yi, w, n);
+                setPixels(0, yi, w, n, model, intOut, 0, w);
+            }
+        } else {
+            // Android bitmaps always store ints (ARGB-8888 direct model)
+            throw new RuntimeException("Byte transfer not supported");
+        }
+    }
+    
+}
diff --git a/awt/com/android/internal/awt/AndroidJavaBlitter.java b/awt/com/android/internal/awt/AndroidJavaBlitter.java
new file mode 100644
index 0000000..423b534
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidJavaBlitter.java
@@ -0,0 +1,536 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed 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 com.android.internal.awt;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.XORComposite;
+import org.apache.harmony.awt.gl.render.Blitter;
+
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+public class AndroidJavaBlitter implements Blitter {
+
+    private Canvas canvas;
+    private Paint paint;
+    private int colorCache;
+        
+    public AndroidJavaBlitter(Canvas c) {
+        this.canvas = c;
+        this.paint = new Paint();
+        this.paint.setStrokeWidth(1);
+    }
+    
+    /**
+     * Instead of multiplication and division we are using values from
+     * Lookup tables.
+     */
+    static byte mulLUT[][]; // Lookup table for multiplication
+    static byte divLUT[][]; // Lookup table for division
+
+    static{
+        mulLUT = new byte[256][256];
+        for(int i = 0; i < 256; i++){
+            for(int j = 0; j < 256; j++){
+                mulLUT[i][j] = (byte)((float)(i * j)/255 + 0.5f);
+            }
+        }
+        divLUT = new byte[256][256];
+        for(int i = 1; i < 256; i++){
+            for(int j = 0; j < i; j++){
+                divLUT[i][j] = (byte)(((float)j / 255) / ((float)i/ 255) * 255 + 0.5f);
+            }
+            for(int j = i; j < 256; j++){
+                divLUT[i][j] = (byte)255;
+            }
+        }
+    }
+
+    final static int AlphaCompositeMode = 1;
+    final static int XORMode = 2;
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            AffineTransform xform, Composite comp, Color bgcolor,
+            MultiRectArea clip) {
+        
+        if(xform == null){
+            blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                    sysxform, comp, bgcolor, clip);
+        }else{
+            double scaleX = xform.getScaleX();
+            double scaleY = xform.getScaleY();
+            double scaledX = dstX / scaleX;
+            double scaledY = dstY / scaleY;
+            AffineTransform at = new AffineTransform();
+            at.setToTranslation(scaledX, scaledY);
+            xform.concatenate(at);
+            sysxform.concatenate(xform);
+            blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
+                    sysxform, comp, bgcolor, clip);
+        }
+
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            Composite comp, Color bgcolor, MultiRectArea clip) {
+        
+        if(sysxform == null) {
+            sysxform = new AffineTransform();
+        }
+        int type = sysxform.getType();
+        switch(type){
+            case AffineTransform.TYPE_TRANSLATION:
+                dstX += sysxform.getTranslateX();
+                dstY += sysxform.getTranslateY();
+            case AffineTransform.TYPE_IDENTITY:
+                simpleBlit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
+                        width, height, comp, bgcolor, clip);
+                break;
+            default:
+                int srcW = srcSurf.getWidth();
+                int srcH = srcSurf.getHeight();
+
+                int w = srcX + width < srcW ? width : srcW - srcX;
+                int h = srcY + height < srcH ? height : srcH - srcY;
+
+                ColorModel srcCM = srcSurf.getColorModel();
+                Raster srcR = srcSurf.getRaster().createChild(srcX, srcY,
+                        w, h, 0, 0, null);
+
+                ColorModel dstCM = dstSurf.getColorModel();
+                WritableRaster dstR = dstSurf.getRaster();
+
+                transformedBlit(srcCM, srcR, 0, 0, dstCM, dstR, dstX, dstY, w, h,
+                        sysxform, comp, bgcolor, clip);
+
+        }
+    }
+
+    public void simpleBlit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+
+        // TODO It's possible, though unlikely that we might encounter non-int[]
+        // data buffers. In this case the following code needs to have several
+        // branches that take this into account.
+        data = (DataBufferInt)srcSurf.getRaster().getDataBuffer();
+        int[] pixels = data.getData();
+        if (!srcSurf.getColorModel().hasAlpha()) {
+            // This wouldn't be necessary if Android supported RGB_888.
+            for (int i = 0; i < pixels.length; i++) {
+                pixels[i] = pixels[i] | 0xff000000;
+            }
+        }
+        bmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
+        canvas.drawBitmap(bmap, dstX, dstY, paint);
+    }
+    
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+
+        javaBlt(srcX, srcY, srcSurf.getWidth(), srcSurf.getHeight(),
+                srcSurf.getColorModel(), srcSurf.getRaster(), dstX, dstY,
+                dstSurf.getWidth(), dstSurf.getHeight(),
+                dstSurf.getColorModel(), dstSurf.getRaster(),
+                width, height, comp, bgcolor, clip);
+
+    }
+    
+    public void javaBlt(int srcX, int srcY, int srcW, int srcH,
+            ColorModel srcCM, Raster srcRast, int dstX, int dstY,
+            int dstW, int dstH, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, Composite comp, Color bgcolor,
+            MultiRectArea clip){
+        
+        int srcX2 = srcW - 1;
+        int srcY2 = srcH - 1;
+        int dstX2 = dstW - 1;
+        int dstY2 = dstH - 1;
+
+        if(srcX < 0){
+            width += srcX;
+            srcX = 0;
+        }
+        if(srcY < 0){
+            height += srcY;
+            srcY = 0;
+        }
+
+        if(dstX < 0){
+            width += dstX;
+            srcX -= dstX;
+            dstX = 0;
+        }
+        if(dstY < 0){
+            height += dstY;
+            srcY -= dstY;
+            dstY = 0;
+        }
+
+        if(srcX > srcX2 || srcY > srcY2) {
+            return;
+        }
+        if(dstX > dstX2 || dstY > dstY2) {
+            return;
+        }
+
+        if(srcX + width > srcX2) {
+            width = srcX2 - srcX + 1;
+        }
+        if(srcY + height > srcY2) {
+            height = srcY2 - srcY + 1;
+        }
+        if(dstX + width > dstX2) {
+            width = dstX2 - dstX + 1;
+        }
+        if(dstY + height > dstY2) {
+            height = dstY2 - dstY + 1;
+        }
+
+        if(width <= 0 || height <= 0) {
+            return;
+        }
+
+        int clipRects[];
+        if(clip != null) {
+            clipRects = clip.rect;
+        } else {
+            clipRects = new int[]{5, 0, 0, dstW - 1, dstH - 1};
+        }
+
+        boolean isAlphaComp = false;
+        int rule = 0;
+        float alpha = 0;
+        boolean isXORComp = false;
+        Color xorcolor = null;
+        CompositeContext cont = null;
+
+        if(comp instanceof AlphaComposite){
+            isAlphaComp = true;
+            AlphaComposite ac = (AlphaComposite) comp;
+            rule = ac.getRule();
+            alpha = ac.getAlpha();
+        }else if(comp instanceof XORComposite){
+            isXORComp = true;
+            XORComposite xcomp = (XORComposite) comp;
+            xorcolor = xcomp.getXORColor();
+        }else{
+            cont = comp.createContext(srcCM, dstCM, null);
+        }
+
+        for(int i = 1; i < clipRects[0]; i += 4){
+            int _sx = srcX;
+            int _sy = srcY;
+
+            int _dx = dstX;
+            int _dy = dstY;
+
+            int _w = width;
+            int _h = height;
+
+            int cx = clipRects[i];          // Clipping left top X
+            int cy = clipRects[i + 1];      // Clipping left top Y
+            int cx2 = clipRects[i + 2];     // Clipping right bottom X
+            int cy2 = clipRects[i + 3];     // Clipping right bottom Y
+
+            if(_dx > cx2 || _dy > cy2 || dstX2 < cx || dstY2 < cy) {
+                continue;
+            }
+
+            if(cx > _dx){
+                int shx = cx - _dx;
+                _w -= shx;
+                _dx = cx;
+                _sx += shx;
+            }
+
+            if(cy > _dy){
+                int shy = cy - _dy;
+                _h -= shy;
+                _dy = cy;
+                _sy += shy;
+            }
+
+            if(_dx + _w > cx2 + 1){
+                _w = cx2 - _dx + 1;
+            }
+
+            if(_dy + _h > cy2 + 1){
+                _h = cy2 - _dy + 1;
+            }
+
+            if(_sx > srcX2 || _sy > srcY2) {
+                continue;
+            }
+
+            if(isAlphaComp){
+                alphaCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
+                        dstCM, dstRast, _w, _h, rule, alpha, bgcolor);
+            }else if(isXORComp){
+                xorCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
+                        dstCM, dstRast, _w, _h, xorcolor);
+            }else{
+                Raster sr = srcRast.createChild(_sx, _sy, _w, _h, 0, 0, null);
+                WritableRaster dr = dstRast.createWritableChild(_dx, _dy,
+                        _w, _h, 0, 0, null);
+                cont.compose(sr, dr, dr);
+            }
+        }
+        
+    }
+
+    DataBufferInt data;
+    Bitmap bmap, bmp;
+    
+    void alphaCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
+            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, int rule, float alpha, Color bgcolor){
+        
+        Object srcPixel = getTransferArray(srcRast, 1);
+        data = (DataBufferInt)srcRast.getDataBuffer();
+        int pix[] = data.getData();
+        bmap = Bitmap.createBitmap(pix, width, height, Bitmap.Config.RGB_565);
+        canvas.drawBitmap(bmap, dstX, dstY, paint);
+    }
+    
+    void render(int[] img, int x, int y, int width, int height) {
+        canvas.drawBitmap(Bitmap.createBitmap(img, width, height, Bitmap.Config.ARGB_8888), x, y, paint);
+    }
+
+    void xorCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
+            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, Color xorcolor){
+
+        data = (DataBufferInt)srcRast.getDataBuffer();
+        int pix[] = data.getData();
+        bmap = Bitmap.createBitmap(pix, width, height, Bitmap.Config.RGB_565);
+        canvas.drawBitmap(bmap, dstX, dstY, paint);
+    }
+    
+    private void transformedBlit(ColorModel srcCM, Raster srcR, int srcX, int srcY,
+            ColorModel dstCM, WritableRaster dstR, int dstX, int dstY,
+            int width, int height, AffineTransform at, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+        
+        data = (DataBufferInt)srcR.getDataBuffer();
+        int[] pixels = data.getData();
+        if (!srcCM.hasAlpha()) {
+            // This wouldn't be necessary if Android supported RGB_888.
+            for (int i = 0; i < pixels.length; i++) {
+                pixels[i] = pixels[i] | 0xff000000;
+            }
+        }
+        bmap = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
+        
+        Matrix tm = new Matrix();
+        tm.setConcat(canvas.getMatrix(), AndroidGraphics2D.createMatrixObj(at));
+        if(at.getType() > 1) {
+            bmp = Bitmap.createBitmap(bmap, 0, 0, width, height, tm, true);
+        } else {
+            bmp = Bitmap.createBitmap(bmap, 0, 0, width, height, tm, false);
+        }
+        canvas.drawBitmap(bmp, dstX + (float)at.getTranslateX(), dstY + (float)at.getTranslateY(), paint);
+    }
+
+    private Rectangle2D getBounds2D(AffineTransform at, Rectangle r) {
+        int x = r.x;
+        int y = r.y;
+        int width = r.width;
+        int height = r.height;
+
+        float[] corners = {
+            x, y,
+            x + width, y,
+            x + width, y + height,
+            x, y + height
+        };
+
+        at.transform(corners, 0, corners, 0, 4);
+
+        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0);
+        bounds.add(corners[2], corners[3]);
+        bounds.add(corners[4], corners[5]);
+        bounds.add(corners[6], corners[7]);
+
+        return bounds;
+    }
+
+    private int compose(int srcRGB, boolean isSrcAlphaPre,
+            int dstRGB, boolean dstHasAlpha, boolean isDstAlphaPre,
+            int rule, int srcConstAlpha){
+
+        int sa, sr, sg, sb, da, dr, dg, db;
+
+        sa = (srcRGB >> 24) & 0xff;
+        sr = (srcRGB >> 16) & 0xff;
+        sg = (srcRGB >> 8) & 0xff;
+        sb = srcRGB & 0xff;
+
+        if(isSrcAlphaPre){
+            sa = mulLUT[srcConstAlpha][sa] & 0xff;
+            sr = mulLUT[srcConstAlpha][sr] & 0xff;
+            sg = mulLUT[srcConstAlpha][sg] & 0xff;
+            sb = mulLUT[srcConstAlpha][sb] & 0xff;
+        }else{
+            sa = mulLUT[srcConstAlpha][sa] & 0xff;
+            sr = mulLUT[sa][sr] & 0xff;
+            sg = mulLUT[sa][sg] & 0xff;
+            sb = mulLUT[sa][sb] & 0xff;
+        }
+
+        da = (dstRGB >> 24) & 0xff;
+        dr = (dstRGB >> 16) & 0xff;
+        dg = (dstRGB >> 8) & 0xff;
+        db = dstRGB & 0xff;
+
+        if(!isDstAlphaPre){
+            dr = mulLUT[da][dr] & 0xff;
+            dg = mulLUT[da][dg] & 0xff;
+            db = mulLUT[da][db] & 0xff;
+        }
+
+        int Fs = 0;
+        int Fd = 0;
+        switch(rule){
+        case AlphaComposite.CLEAR:
+            break;
+
+        case AlphaComposite.DST:
+            Fd = 255;
+            break;
+
+        case AlphaComposite.DST_ATOP:
+            Fs = 255 - da;
+            Fd = sa;
+            break;
+
+        case AlphaComposite.DST_IN:
+            Fd = sa;
+            break;
+
+        case AlphaComposite.DST_OUT:
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.DST_OVER:
+            Fs = 255 - da;
+            Fd = 255;
+            break;
+
+        case AlphaComposite.SRC:
+            Fs = 255;
+            break;
+
+        case AlphaComposite.SRC_ATOP:
+            Fs = da;
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.SRC_IN:
+            Fs = da;
+            break;
+
+        case AlphaComposite.SRC_OUT:
+            Fs = 255 - da;
+            break;
+
+        case AlphaComposite.SRC_OVER:
+            Fs = 255;
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.XOR:
+            Fs = 255 - da;
+            Fd = 255 - sa;
+            break;
+        }
+        dr = (mulLUT[sr][Fs] & 0xff) + (mulLUT[dr][Fd] & 0xff);
+        dg = (mulLUT[sg][Fs] & 0xff) + (mulLUT[dg][Fd] & 0xff);
+        db = (mulLUT[sb][Fs] & 0xff) + (mulLUT[db][Fd] & 0xff);
+
+        da = (mulLUT[sa][Fs] & 0xff) + (mulLUT[da][Fd] & 0xff);
+
+        if(!isDstAlphaPre){
+            if(da != 255){
+                dr = divLUT[da][dr] & 0xff;
+                dg = divLUT[da][dg] & 0xff;
+                db = divLUT[da][db] & 0xff;
+            }
+        }
+        if(!dstHasAlpha) {
+            da = 0xff;
+        }
+        dstRGB = (da << 24) | (dr << 16) | (dg << 8) | db;
+
+        return dstRGB;
+
+    }
+    
+    /**
+     * Allocate an array that can be use to store the result for a 
+     * Raster.getDataElements call.
+     * @param raster  Raster (type) where the getDataElements call will be made. 
+     * @param nbPixels  How many pixels to store in the array at most
+     * @return the result array or null
+     */
+    private Object getTransferArray(Raster raster, int nbPixels) {
+        int transferType = raster.getTransferType();
+        int nbDataElements = raster.getSampleModel().getNumDataElements();
+        int n = nbDataElements * nbPixels;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            return new byte[n];
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            return new short[n];
+        case DataBuffer.TYPE_INT:
+            return new int[n];
+        case DataBuffer.TYPE_FLOAT:
+            return new float[n];
+        case DataBuffer.TYPE_DOUBLE:
+            return new double[n];
+        case DataBuffer.TYPE_UNDEFINED:
+        default:
+            return null;
+        }
+    }
+    
+    /**
+     * Draw a pixel
+     */
+    private void dot(int x, int y, int clr) {
+        if (colorCache != clr) {
+            paint.setColor(clr);  
+            colorCache = clr;
+        }
+        canvas.drawLine(x, y, x + 1, y + 1, paint);
+    }
+}
diff --git a/awt/com/android/internal/awt/AndroidNativeEventQueue.java b/awt/com/android/internal/awt/AndroidNativeEventQueue.java
new file mode 100644
index 0000000..fc30614
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidNativeEventQueue.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed 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 com.android.internal.awt;
+
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+
+public class AndroidNativeEventQueue extends NativeEventQueue {
+    
+    private Object eventMonitor;
+    
+    public AndroidNativeEventQueue() {
+        super();
+        eventMonitor = getEventMonitor();
+    }
+
+    @Override
+    public void awake() {
+        synchronized (eventMonitor) {
+            eventMonitor.notify();
+        }
+    }
+
+    @Override
+    public void dispatchEvent() {
+        //???AWT
+        System.out.println(getClass()+": empty method called");
+    }
+
+    @Override
+    public long getJavaWindow() {
+        //???AWT
+        System.out.println(getClass()+": empty method called");
+        return 0;
+    }
+
+    @Override
+    public void performLater(Task task) {
+        //???AWT
+        System.out.println(getClass()+": empty method called");
+    }
+
+    @Override
+    public void performTask(Task task) {
+        //???AWT
+        System.out.println(getClass()+": empty method called");
+    }
+
+    @Override
+    public boolean waitEvent() {
+        while (isEmpty() ) {
+            synchronized (eventMonitor) {
+                try {
+                    eventMonitor.wait(1000);
+                } catch (InterruptedException ignore) {
+                }
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/awt/com/android/internal/awt/AndroidWTK.java b/awt/com/android/internal/awt/AndroidWTK.java
new file mode 100644
index 0000000..1609d11
--- /dev/null
+++ b/awt/com/android/internal/awt/AndroidWTK.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed 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 com.android.internal.awt;
+
+import java.awt.GraphicsDevice;
+
+import org.apache.harmony.awt.wtk.CursorFactory;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+import org.apache.harmony.awt.wtk.NativeIM;
+import org.apache.harmony.awt.wtk.NativeMouseInfo;
+import org.apache.harmony.awt.wtk.NativeRobot;
+import org.apache.harmony.awt.wtk.SystemProperties;
+import org.apache.harmony.awt.wtk.WTK;
+import org.apache.harmony.awt.wtk.WindowFactory;
+
+public class AndroidWTK extends WTK {
+
+    private AndroidGraphicsFactory mAgf;
+    private AndroidNativeEventQueue mAneq;
+    
+    @Override
+    public CursorFactory getCursorFactory() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public GraphicsFactory getGraphicsFactory() {
+        if(mAgf == null) {
+            mAgf = new AndroidGraphicsFactory();
+        }
+        return mAgf;
+    }
+
+    @Override
+    public NativeEventQueue getNativeEventQueue() {
+        if(mAneq == null) {
+            mAneq = new AndroidNativeEventQueue();
+        }
+        return mAneq;
+    }
+
+    @Override
+    public NativeIM getNativeIM() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NativeMouseInfo getNativeMouseInfo() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NativeRobot getNativeRobot(GraphicsDevice screen) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SystemProperties getSystemProperties() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public WindowFactory getWindowFactory() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
diff --git a/awt/com/android/internal/awt/AwtFactory.java b/awt/com/android/internal/awt/AwtFactory.java
new file mode 100644
index 0000000..6e667b2
--- /dev/null
+++ b/awt/com/android/internal/awt/AwtFactory.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed 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 com.android.internal.awt;
+
+import java.awt.Graphics2D;
+import java.awt.Toolkit;
+
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+
+public class AwtFactory {
+    
+    private static GraphicsFactory gf;
+    
+    /**
+     * Use this method to get acces to AWT drawing primitives and to
+     * render into the surface area of a Android widget. Origin and 
+     * clip of the returned graphics object are the same as in the
+     * corresponding Android widget. 
+     * 
+     * @param c Canvas of the android widget to draw into
+     * @param p The default drawing parameters such as font, 
+     * stroke, foreground and background colors, etc.
+     * @return The AWT Graphics object that makes all AWT 
+     * drawing primitives available in the androind world.
+     */
+    public static Graphics2D getAwtGraphics(Canvas c, Paint p) {
+        // AWT?? TODO: test it!
+        if (null == gf) {
+            Toolkit tk = Toolkit.getDefaultToolkit();
+            gf = tk.getGraphicsFactory();
+        }
+        return gf.getGraphics2D(c, p);
+    }
+
+}
diff --git a/awt/com/android/internal/awt/ImageOutputStreamWrapper.java b/awt/com/android/internal/awt/ImageOutputStreamWrapper.java
new file mode 100644
index 0000000..92185fd
--- /dev/null
+++ b/awt/com/android/internal/awt/ImageOutputStreamWrapper.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2007, The Android Open Source Project
+ *
+ * Licensed 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 com.android.internal.awt;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.imageio.stream.ImageOutputStream;
+
+public class ImageOutputStreamWrapper extends OutputStream {
+	
+	protected ImageOutputStream mIos;
+	
+	private byte[] mBuff;
+	
+	public ImageOutputStreamWrapper(ImageOutputStream ios) {
+		if (null == ios) {
+			throw new IllegalArgumentException("ImageOutputStream must not be null");
+		}
+		this.mIos = ios;
+		this.mBuff = new byte[1];
+	}
+
+	public ImageOutputStream getImageOutputStream() {
+		return mIos;
+	}
+	
+	@Override
+	public void write(int oneByte) throws IOException {
+		mBuff[0] = (byte)oneByte;
+		mIos.write(mBuff, 0, 1);
+	}
+
+	public void write(byte[] b) throws IOException {
+		mIos.write(b, 0, b.length);
+	}
+	
+	public void write(byte[] b, int off, int len) throws IOException {
+		mIos.write(b, off, len);
+	}
+	
+	public void flush() throws IOException {
+		mIos.flush();
+	}
+	
+    public void close() throws IOException {
+    	if (mIos == null) {
+    		throw new IOException("Stream already closed");
+    	}
+        mIos = null;
+    }
+}
diff --git a/awt/java/awt/AWTEvent.java b/awt/java/awt/AWTEvent.java
new file mode 100644
index 0000000..1ed9a37
--- /dev/null
+++ b/awt/java/awt/AWTEvent.java
@@ -0,0 +1,618 @@
+/*
+ *  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 Dmitry A. Durnev, Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.util.EventObject;
+import java.util.Hashtable;
+import java.util.EventListener;
+
+import java.awt.event.*;
+
+/**
+ * The abstract AWT events is base class for all AWT events. 
+ * This class and its subclasses supercede the original java.awt.Event class.
+ */
+public abstract class AWTEvent extends EventObject {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1825314779160409405L;
+
+    /** The Constant COMPONENT_EVENT_MASK indicates the event relates to a component. */
+    public static final long COMPONENT_EVENT_MASK = 1;
+
+    /** The Constant CONTAINER_EVENT_MASK indicates the event relates to a container. */
+    public static final long CONTAINER_EVENT_MASK = 2;
+
+    /** The Constant FOCUS_EVENT_MASK indicates the event relates to the focus. */
+    public static final long FOCUS_EVENT_MASK = 4;
+
+    /** The Constant KEY_EVENT_MASK indicates the event relates to a key. */
+    public static final long KEY_EVENT_MASK = 8;
+
+    /** The Constant MOUSE_EVENT_MASK indicates the event relates to the mouse. */
+    public static final long MOUSE_EVENT_MASK = 16;
+
+    /** The Constant MOUSE_MOTION_EVENT_MASK indicates the event relates to a mouse motion. */
+    public static final long MOUSE_MOTION_EVENT_MASK = 32;
+
+    /** The Constant WINDOW_EVENT_MASK indicates the event relates to a window. */
+    public static final long WINDOW_EVENT_MASK = 64;
+
+    /** The Constant ACTION_EVENT_MASK indicates the event relates to an action. */
+    public static final long ACTION_EVENT_MASK = 128;
+
+    /** The Constant ADJUSTMENT_EVENT_MASK indicates the event relates to an adjustment. */
+    public static final long ADJUSTMENT_EVENT_MASK = 256;
+
+    /** The Constant ITEM_EVENT_MASK indicates the event relates to an item. */
+    public static final long ITEM_EVENT_MASK = 512;
+
+    /** The Constant TEXT_EVENT_MASK indicates the event relates to text. */
+    public static final long TEXT_EVENT_MASK = 1024;
+
+    /** The Constant INPUT_METHOD_EVENT_MASK indicates the event relates to an input method. */
+    public static final long INPUT_METHOD_EVENT_MASK = 2048;
+
+    /** The Constant PAINT_EVENT_MASK indicates the event relates to a paint method. */
+    public static final long PAINT_EVENT_MASK = 8192;
+
+    /** The Constant INVOCATION_EVENT_MASK indicates the event relates to a method invocation. */
+    public static final long INVOCATION_EVENT_MASK = 16384;
+
+    /** The Constant HIERARCHY_EVENT_MASK indicates the event relates to a hierarchy. */
+    public static final long HIERARCHY_EVENT_MASK = 32768;
+
+    /** 
+     * The Constant HIERARCHY_BOUNDS_EVENT_MASK indicates the event relates to hierarchy bounds.
+     */
+    public static final long HIERARCHY_BOUNDS_EVENT_MASK = 65536;
+
+    /** The Constant MOUSE_WHEEL_EVENT_MASK indicates the event relates to the mouse wheel. */
+    public static final long MOUSE_WHEEL_EVENT_MASK = 131072;
+
+    /** The Constant WINDOW_STATE_EVENT_MASK indicates the event relates to a window state. */
+    public static final long WINDOW_STATE_EVENT_MASK = 262144;
+
+    /** The Constant WINDOW_FOCUS_EVENT_MASK indicates the event relates to a window focus. */
+    public static final long WINDOW_FOCUS_EVENT_MASK = 524288;
+
+    /** The Constant RESERVED_ID_MAX indicates the maximum value for reserved 
+     * AWT event IDs.
+     */
+    public static final int RESERVED_ID_MAX = 1999;
+
+    /** The Constant eventsMap. */
+    private static final Hashtable<Integer, EventDescriptor> eventsMap = new Hashtable<Integer, EventDescriptor>();
+
+    /** The converter. */
+    private static EventConverter converter;
+
+    /** The ID of the event. */
+    protected int id;
+
+    /** 
+     * The consumed indicates whether or not the event is sent back down to 
+     * the peer once the source has processed it (false means it's sent to the peer,
+     * true means it's not).
+     */ 
+    protected boolean consumed;
+
+    /** The dispatched by kfm. */
+    boolean dispatchedByKFM;
+    
+    /** The is posted. */
+    transient boolean isPosted;
+
+    static {
+        eventsMap.put(new Integer(KeyEvent.KEY_TYPED),
+                new EventDescriptor(KEY_EVENT_MASK, KeyListener.class));
+        eventsMap.put(new Integer(KeyEvent.KEY_PRESSED),
+                new EventDescriptor(KEY_EVENT_MASK, KeyListener.class));
+        eventsMap.put(new Integer(KeyEvent.KEY_RELEASED),
+                new EventDescriptor(KEY_EVENT_MASK, KeyListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_CLICKED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_PRESSED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_RELEASED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_MOVED),
+                new EventDescriptor(MOUSE_MOTION_EVENT_MASK, MouseMotionListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_ENTERED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_EXITED),
+                new EventDescriptor(MOUSE_EVENT_MASK, MouseListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_DRAGGED),
+                new EventDescriptor(MOUSE_MOTION_EVENT_MASK, MouseMotionListener.class));
+        eventsMap.put(new Integer(MouseEvent.MOUSE_WHEEL),
+                new EventDescriptor(MOUSE_WHEEL_EVENT_MASK, MouseWheelListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_MOVED),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_RESIZED),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_SHOWN),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(ComponentEvent.COMPONENT_HIDDEN),
+                new EventDescriptor(COMPONENT_EVENT_MASK, ComponentListener.class));
+        eventsMap.put(new Integer(FocusEvent.FOCUS_GAINED),
+                new EventDescriptor(FOCUS_EVENT_MASK, FocusListener.class));
+        eventsMap.put(new Integer(FocusEvent.FOCUS_LOST),
+                new EventDescriptor(FOCUS_EVENT_MASK, FocusListener.class));
+        eventsMap.put(new Integer(PaintEvent.PAINT),
+                new EventDescriptor(PAINT_EVENT_MASK, null));
+        eventsMap.put(new Integer(PaintEvent.UPDATE),
+                new EventDescriptor(PAINT_EVENT_MASK, null));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_OPENED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_CLOSING),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_CLOSED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_DEICONIFIED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_ICONIFIED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_STATE_CHANGED),
+                new EventDescriptor(WINDOW_STATE_EVENT_MASK, WindowStateListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_LOST_FOCUS),
+                new EventDescriptor(WINDOW_FOCUS_EVENT_MASK, WindowFocusListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_GAINED_FOCUS),
+                new EventDescriptor(WINDOW_FOCUS_EVENT_MASK, WindowFocusListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_DEACTIVATED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(WindowEvent.WINDOW_ACTIVATED),
+                new EventDescriptor(WINDOW_EVENT_MASK, WindowListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.HIERARCHY_CHANGED),
+                new EventDescriptor(HIERARCHY_EVENT_MASK, HierarchyListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.ANCESTOR_MOVED),
+                new EventDescriptor(HIERARCHY_BOUNDS_EVENT_MASK, HierarchyBoundsListener.class));
+        eventsMap.put(new Integer(HierarchyEvent.ANCESTOR_RESIZED),
+                new EventDescriptor(HIERARCHY_BOUNDS_EVENT_MASK, HierarchyBoundsListener.class));
+        eventsMap.put(new Integer(ContainerEvent.COMPONENT_ADDED),
+                new EventDescriptor(CONTAINER_EVENT_MASK, ContainerListener.class));
+        eventsMap.put(new Integer(ContainerEvent.COMPONENT_REMOVED),
+                new EventDescriptor(CONTAINER_EVENT_MASK, ContainerListener.class));
+        eventsMap.put(new Integer(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED),
+                new EventDescriptor(INPUT_METHOD_EVENT_MASK, InputMethodListener.class));
+        eventsMap.put(new Integer(InputMethodEvent.CARET_POSITION_CHANGED),
+                new EventDescriptor(INPUT_METHOD_EVENT_MASK, InputMethodListener.class));
+        eventsMap.put(new Integer(InvocationEvent.INVOCATION_DEFAULT),
+                new EventDescriptor(INVOCATION_EVENT_MASK, null));
+        eventsMap.put(new Integer(ItemEvent.ITEM_STATE_CHANGED),
+                new EventDescriptor(ITEM_EVENT_MASK, ItemListener.class));
+        eventsMap.put(new Integer(TextEvent.TEXT_VALUE_CHANGED),
+                new EventDescriptor(TEXT_EVENT_MASK, TextListener.class));
+        eventsMap.put(new Integer(ActionEvent.ACTION_PERFORMED),
+                new EventDescriptor(ACTION_EVENT_MASK, ActionListener.class));
+        eventsMap.put(new Integer(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED),
+                new EventDescriptor(ADJUSTMENT_EVENT_MASK, AdjustmentListener.class));
+        converter = new EventConverter();
+    }
+    
+    /**
+     * Instantiates a new AWT event from the specified Event object.
+     * 
+     * @param event the Event object.
+     */
+    public AWTEvent(Event event) {
+        this(event.target, event.id);
+    }
+
+    /**
+     * Instantiates a new AWT event with the specified object and type.
+     * 
+     * @param source the source Object.
+     * @param id the event's type.
+     */
+    public AWTEvent(Object source, int id) {
+        super(source);
+        this.id = id;
+        consumed = false;
+    }
+
+    /**
+     * Gets the event's type.
+     * 
+     * @return the event type ID.
+     */
+    public int getID() {
+        return id;
+    }
+
+    /**
+     * Sets a new source for the AWTEvent.
+     * 
+     * @param newSource the new source Object for the AWTEvent.
+     */
+    public void setSource(Object newSource) {
+        source = newSource;
+    }
+
+    /**
+     * Returns a String representation of the AWTEvent.
+     * 
+     * @return the String representation of the AWTEvent.
+     */
+    @Override
+    public String toString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * AWTEvent event = new AWTEvent(new Component(){}, 1){};
+         * System.out.println(event);
+         */
+        String name = ""; //$NON-NLS-1$
+        
+        if (source instanceof Component && (source != null)) {
+            Component comp = (Component) getSource();
+            name = comp.getName();
+            if (name == null) {
+                name = ""; //$NON-NLS-1$
+            }
+        }
+        
+        return (getClass().getName() + "[" + paramString() + "]" //$NON-NLS-1$ //$NON-NLS-2$
+                + " on " + (name.length() > 0 ? name : source)); //$NON-NLS-1$
+    }
+
+    /**
+     * Returns a string representation of the AWTEvent state. 
+     *  
+     * @return a string representation of the AWTEvent state.
+     */
+    public String paramString() {
+        //nothing to implement: all event types must override this method
+        return ""; //$NON-NLS-1$
+    }
+
+    /**
+     * Checks whether or not this AWTEvent has been consumed.
+     * 
+     * @return true, if this AWTEvent has been consumed, false otherwise.
+     */
+    protected boolean isConsumed() {
+        return consumed;
+    }
+
+    /**
+     * Consumes the AWTEvent.
+     */
+    protected void consume() {
+       consumed = true;
+    }
+
+    /**
+     * Convert AWTEvent object to a corresponding (deprecated) Event object.
+     * 
+     * @return new Event object which is a converted AWTEvent object or null
+     * if the conversion is not possible
+     */
+    Event getEvent() {
+        
+        if (id == ActionEvent.ACTION_PERFORMED) {
+            ActionEvent ae = (ActionEvent) this;
+            return converter.convertActionEvent(ae);
+
+        } else if (id == AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED) {
+            AdjustmentEvent ae = (AdjustmentEvent) this;
+            return converter.convertAdjustmentEvent(ae);
+
+//???AWT
+//        } else if (id == ComponentEvent.COMPONENT_MOVED
+//                && source instanceof Window) {
+//            //the only type of Component events is COMPONENT_MOVED on window
+//            ComponentEvent ce = (ComponentEvent) this;
+//            return converter.convertComponentEvent(ce);
+
+        } else if (id >= FocusEvent.FOCUS_FIRST && id <= FocusEvent.FOCUS_LAST) {
+            //nothing to convert
+
+//???AWT
+//        } else if (id == ItemEvent.ITEM_STATE_CHANGED) {
+//            ItemEvent ie = (ItemEvent) this;
+//            return converter.convertItemEvent(ie);
+
+        } else if (id == KeyEvent.KEY_PRESSED || id == KeyEvent.KEY_RELEASED) {
+            KeyEvent ke = (KeyEvent) this;
+            return converter.convertKeyEvent(ke);
+        } else if (id >= MouseEvent.MOUSE_FIRST && id <= MouseEvent.MOUSE_LAST) {
+            MouseEvent me = (MouseEvent) this;
+            return converter.convertMouseEvent(me);
+        } else if (id == WindowEvent.WINDOW_CLOSING
+                || id == WindowEvent.WINDOW_ICONIFIED
+                || id == WindowEvent.WINDOW_DEICONIFIED) {
+            //nothing to convert
+        } else {
+            return null;
+        }
+        return new Event(source, id, null);
+    }
+
+
+    /**
+     * The Class EventDescriptor.
+     */
+    static final class EventDescriptor {
+
+        /** The event mask. */
+        final long eventMask;
+
+        /** The listener type. */
+        final Class<? extends EventListener> listenerType;
+
+        /**
+         * Instantiates a new event descriptor.
+         * 
+         * @param eventMask the event mask
+         * @param listenerType the listener type
+         */
+        EventDescriptor(long eventMask, Class<? extends EventListener> listenerType) {
+            this.eventMask = eventMask;
+            this.listenerType = listenerType;
+        }
+
+    }
+    
+    /**
+     * The Class EventTypeLookup.
+     */
+    static final class EventTypeLookup {
+        
+        /** The last event. */
+        private AWTEvent lastEvent = null;
+        
+        /** The last event descriptor. */
+        private EventDescriptor lastEventDescriptor = null;
+
+        /**
+         * Gets the event descriptor.
+         * 
+         * @param event the event
+         * 
+         * @return the event descriptor
+         */
+        EventDescriptor getEventDescriptor(AWTEvent event) {
+            synchronized (this) {
+                if (event != lastEvent) {
+                    lastEvent = event;
+                    lastEventDescriptor = eventsMap.get(new Integer(event.id));
+                }
+
+                return lastEventDescriptor;
+            }
+        }
+
+        /**
+         * Gets the event mask.
+         * 
+         * @param event the event
+         * 
+         * @return the event mask
+         */
+        long getEventMask(AWTEvent event) {
+            final EventDescriptor ed = getEventDescriptor(event);
+            return ed == null ? -1 : ed.eventMask;
+        }
+    }
+
+    /**
+     * The Class EventConverter.
+     */
+    static final class EventConverter {
+        
+        /** The Constant OLD_MOD_MASK. */
+        static final int OLD_MOD_MASK = Event.ALT_MASK | Event.CTRL_MASK
+        | Event.META_MASK | Event.SHIFT_MASK;
+
+        /**
+         * Convert action event.
+         * 
+         * @param ae the ae
+         * 
+         * @return the event
+         */
+        Event convertActionEvent(ActionEvent ae) {
+            Event evt = new Event(ae.getSource(), ae.getID(), ae.getActionCommand());
+            evt.when = ae.getWhen();
+            evt.modifiers = ae.getModifiers() & OLD_MOD_MASK;
+
+           /* if (source instanceof Button) {
+                arg = ((Button) source).getLabel();
+            } else if (source instanceof Checkbox) {
+                arg = new Boolean(((Checkbox) source).getState());
+            } else if (source instanceof CheckboxMenuItem) {
+                arg = ((CheckboxMenuItem) source).getLabel();
+            } else if (source instanceof Choice) {
+                arg = ((Choice) source).getSelectedItem();
+            } else if (source instanceof List) {
+                arg = ((List) source).getSelectedItem();
+            } else if (source instanceof MenuItem) {
+                arg = ((MenuItem) source).getLabel();
+            } else if (source instanceof TextField) {
+                arg = ((TextField) source).getText();
+            }
+*/
+            return evt;
+        }
+
+
+        /**
+         * Convert adjustment event.
+         * 
+         * @param ae the ae
+         * 
+         * @return the event
+         */
+        Event convertAdjustmentEvent(AdjustmentEvent ae) {
+            //TODO: Event.SCROLL_BEGIN/SCROLL_END
+            return new Event(ae.source, ae.id + ae.getAdjustmentType() - 1,
+                    new Integer(ae.getValue()));
+        }
+
+        /**
+         * Convert component event.
+         * 
+         * @param ce the ce
+         * 
+         * @return the event
+         */
+        Event convertComponentEvent(ComponentEvent ce) {
+            Component comp = ce.getComponent();
+            Event evt = new Event(comp, Event.WINDOW_MOVED, null);
+            evt.x = comp.getX();
+            evt.y = comp.getY();
+            return evt;
+        }
+
+        //???AWT
+        /*
+        Event convertItemEvent(ItemEvent ie) {
+            int oldId = ie.id + ie.getStateChange() - 1;
+            Object source = ie.source;
+            int idx = -1;
+            if (source instanceof List) {
+                List list = (List) source;
+                idx = list.getSelectedIndex();
+            }
+            else if (source instanceof Choice) {
+                Choice choice = (Choice) source;
+                idx = choice.getSelectedIndex();
+            }
+            Object arg = idx >= 0 ? new Integer(idx) : null;
+            return new Event(source, oldId, arg);
+        }
+        */
+        
+        /**
+         * Convert key event.
+         * 
+         * @param ke the ke
+         * 
+         * @return the event
+         */
+        Event convertKeyEvent(KeyEvent ke) {
+            int oldId = ke.id;
+            //leave only old Event's modifiers
+
+            int mod = ke.getModifiers() & OLD_MOD_MASK;
+            Component comp = ke.getComponent();
+            char keyChar = ke.getKeyChar();
+            int keyCode = ke.getKeyCode();
+            int key = convertKey(keyChar, keyCode);
+            if (key >= Event.HOME && key <= Event.INSERT) {
+                oldId += 2; //non-ASCII key -> action key
+            }
+            return new Event(comp, ke.getWhen(), oldId, 0, 0, key, mod);
+        }
+
+        /**
+         * Convert mouse event.
+         * 
+         * @param me the me
+         * 
+         * @return the event
+         */
+        Event convertMouseEvent(MouseEvent me) {
+            int id = me.id;
+            if (id != MouseEvent.MOUSE_CLICKED) {
+                Event evt = new Event(me.source, id, null);
+                evt.x = me.getX();
+                evt.y = me.getY();
+                int mod = me.getModifiers();
+                //in Event modifiers mean button number for mouse events:
+                evt.modifiers = mod & (Event.ALT_MASK | Event.META_MASK);
+                if (id == MouseEvent.MOUSE_PRESSED) {
+                    evt.clickCount = me.getClickCount();
+                }
+                return evt;
+            }
+            return null;
+        }
+        
+        /**
+         * Convert key.
+         * 
+         * @param keyChar the key char
+         * @param keyCode the key code
+         * 
+         * @return the int
+         */
+        int convertKey(char keyChar, int keyCode) {
+            int key;
+            //F1 - F12
+            if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) {
+                key = Event.F1 + keyCode - KeyEvent.VK_F1;
+            } else {
+                switch (keyCode) {
+                default: //non-action key
+                    key = keyChar;
+                    break;
+                //action keys:
+                case KeyEvent.VK_HOME:
+                    key = Event.HOME;
+                    break;
+                case KeyEvent.VK_END:
+                    key = Event.END;
+                    break;
+                case KeyEvent.VK_PAGE_UP:
+                    key = Event.PGUP;
+                    break;
+                case KeyEvent.VK_PAGE_DOWN:
+                    key = Event.PGDN;
+                    break;
+                case KeyEvent.VK_UP:
+                    key = Event.UP;
+                    break;
+                case KeyEvent.VK_DOWN:
+                    key = Event.DOWN;
+                    break;
+                case KeyEvent.VK_LEFT:
+                    key = Event.LEFT;
+                    break;
+                case KeyEvent.VK_RIGHT:
+                    key = Event.RIGHT;
+                    break;
+                case KeyEvent.VK_PRINTSCREEN:
+                    key = Event.PRINT_SCREEN;
+                    break;
+                case KeyEvent.VK_SCROLL_LOCK:
+                    key = Event.SCROLL_LOCK;
+                    break;
+                case KeyEvent.VK_CAPS_LOCK:
+                    key = Event.CAPS_LOCK;
+                    break;
+                case KeyEvent.VK_NUM_LOCK:
+                    key = Event.NUM_LOCK;
+                    break;
+                case KeyEvent.VK_PAUSE:
+                    key = Event.PAUSE;
+                    break;
+                case KeyEvent.VK_INSERT:
+                    key = Event.INSERT;
+                    break;
+                }
+            }
+            return key;
+        }
+
+    }
+
+}
diff --git a/awt/java/awt/AWTException.java b/awt/java/awt/AWTException.java
new file mode 100644
index 0000000..70ce6e1
--- /dev/null
+++ b/awt/java/awt/AWTException.java
@@ -0,0 +1,43 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+
+/**
+ * The AWTException class is used to provide notification and information
+ * about AWT errors.
+ */
+public class AWTException extends Exception {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1900414231151323879L;
+
+    /**
+     * Instantiates a new AWT exception with the specified message.
+     * 
+     * @param msg the specific message for current exception.
+     */
+    public AWTException(String msg) {
+        super(msg);
+    }
+
+}
+
diff --git a/awt/java/awt/AWTKeyStroke.java b/awt/java/awt/AWTKeyStroke.java
new file mode 100644
index 0000000..5e7de4e
--- /dev/null
+++ b/awt/java/awt/AWTKeyStroke.java
@@ -0,0 +1,678 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The AWTKeyStroke holds all of the information for the complete act of 
+ * typing a character. This includes the events that are generated when 
+ * the key is pressed, released, or typed (pressed and released generating
+ * a unicode character result) which are associated with the event
+ * objects KeyEvent.KEY_PRESSED, KeyEvent.KEY_RELEASED, or KeyEvent.KEY_TYPED.
+ * It also holds information about which modifiers (such as control or 
+ * shift) were used in conjunction with the keystroke. The following masks 
+ * are available to identify the modifiers:
+ * <ul>
+ * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+ * <li>java.awt.event.InputEvent.ALT_MASK</li>
+ * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+ * <li>java.awt.event.InputEvent.META_MASK</li>  
+ * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+ * </ul>  
+ * <br>
+ *  The AWTKeyStroke is unique, and applications should not create their own 
+ *  instances of AWTKeyStroke. All applications should use getAWTKeyStroke 
+ *  methods for obtaining instances of AWTKeyStroke.
+ */
+public class AWTKeyStroke implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -6430539691155161871L;
+
+    /** The Constant cache. */
+    private static final Map<AWTKeyStroke, AWTKeyStroke> cache = new HashMap<AWTKeyStroke, AWTKeyStroke>(); //Map<AWTKeyStroke, ? extends AWTKeyStroke>
+    
+    /** The Constant keyEventTypesMap. */
+    private static final Map<Integer, String> keyEventTypesMap = new HashMap<Integer, String>(); //Map<int, String>
+
+    private static Constructor<?> subConstructor;   
+
+    static {
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_PRESSED), "pressed"); //$NON-NLS-1$
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_RELEASED), "released"); //$NON-NLS-1$
+        keyEventTypesMap.put(new Integer(KeyEvent.KEY_TYPED), "typed"); //$NON-NLS-1$
+    }
+
+    /** The key char. */
+    private char keyChar;
+    
+    /** The key code. */
+    private int keyCode;
+    
+    /** The modifiers. */
+    private int modifiers;
+    
+    /** The on key release. */
+    private boolean onKeyRelease;
+    
+    /**
+     * Instantiates a new AWTKeyStroke. 
+     * getAWTKeyStroke method should be used by applications code.  
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease true if AWTKeyStroke is for a key release, overwise false. 
+     */
+    protected AWTKeyStroke(char keyChar, int keyCode, int modifiers,
+            boolean onKeyRelease)
+    {
+       setAWTKeyStroke(keyChar, keyCode, modifiers, onKeyRelease);
+    }
+
+    /** Sets the awt key stroke.
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease the on key release
+     */
+    private void setAWTKeyStroke( char keyChar, int keyCode, int modifiers,
+            boolean onKeyRelease)
+    {
+        this.keyChar = keyChar;
+        this.keyCode = keyCode;
+        this.modifiers = modifiers;
+        this.onKeyRelease = onKeyRelease;
+    }
+    
+    /**
+     * Instantiates a new AWTKeyStroke with default parameters:
+     * KeyEvent.CHAR_UNDEFINED key char, KeyEvent.VK_UNDEFINED key code,
+     * without modifiers and false key realised value.
+     */
+    protected AWTKeyStroke() {
+        this(KeyEvent.CHAR_UNDEFINED, KeyEvent.VK_UNDEFINED, 0, false);
+    }
+
+    /**
+     * Returns the unique number value for AWTKeyStroke object.
+     * 
+     * @return the int unique value of the AWTKeyStroke object.
+     */
+    @Override
+    public int hashCode() {
+        return modifiers + ( keyCode != KeyEvent.VK_UNDEFINED ?
+                keyCode : keyChar) + (onKeyRelease ? -1 : 0);
+    }
+
+    /**
+     * Gets the set of modifiers for the AWTKeyStroke object.
+     * 
+     * @return the int value which contains modifiers.
+     */
+    public final int getModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * Compares the AWTKeyStroke object to the specified object.
+     * 
+     * @return true, if objects are identical, overwise false.
+     */
+    @Override
+    public final boolean equals(Object anObject) {
+        if (anObject instanceof AWTKeyStroke) {
+            AWTKeyStroke key = (AWTKeyStroke)anObject;
+            return ((key.keyCode == keyCode) && (key.keyChar == keyChar) &&
+                    (key.modifiers == modifiers) &&
+                    (key.onKeyRelease == onKeyRelease));
+        }
+        return false;
+    }
+
+    /**
+     * Returns the string representation of the AWTKeyStroke.
+     * This string should contain key stroke properties.
+     * 
+     * @return the string representation of the AWTKeyStroke.
+     */
+    @Override
+    public String toString() {
+        int type = getKeyEventType();
+        return InputEvent.getModifiersExText(getModifiers()) + " " + //$NON-NLS-1$
+            keyEventTypesMap.get(new Integer(type)) +  " " + //$NON-NLS-1$
+            (type == KeyEvent.KEY_TYPED ? new String(new char[] {keyChar}) :
+                                          KeyEvent.getKeyText(keyCode));
+    }
+
+    /**
+     * Gets the key code for the AWTKeyStroke object.
+     * 
+     * @return the key code for the AWTKeyStroke object.
+     */
+    public final int getKeyCode() {
+        return keyCode;
+    }
+
+    /**
+     * Gets the key character for the AWTKeyStroke object.
+     * 
+     * @return the key character for the AWTKeyStroke object.
+     */
+    public final char getKeyChar() {
+        return keyChar;
+    }
+
+    /**
+     * Gets the AWT key stroke.
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease the on key release
+     * 
+     * @return the AWT key stroke
+     */
+    private static AWTKeyStroke getAWTKeyStroke(char keyChar, int keyCode,
+                                                int modifiers,
+                                                boolean onKeyRelease) {
+        AWTKeyStroke key = newInstance(keyChar, keyCode, modifiers, onKeyRelease);
+
+        AWTKeyStroke value = cache.get(key);
+        if (value == null) {
+            value = key;
+            cache.put(key, value);
+        }
+        return value;
+    }
+
+    /**
+     * New instance.
+     * 
+     * @param keyChar the key char
+     * @param keyCode the key code
+     * @param modifiers the modifiers
+     * @param onKeyRelease the on key release
+     * 
+     * @return the AWT key stroke
+     */
+    private static AWTKeyStroke newInstance(char keyChar, int keyCode,
+                                            int modifiers,
+                                            boolean onKeyRelease) {
+        AWTKeyStroke key;
+        //???AWT
+//        if (subConstructor == null) {
+            key = new AWTKeyStroke();
+        //???AWT
+//        } else {
+//            try {
+//                key = (AWTKeyStroke) subConstructor.newInstance();
+//            } catch (Exception e) {
+//                throw new RuntimeException(e);
+//            }
+//        }
+        int allModifiers = getAllModifiers(modifiers);
+        key.setAWTKeyStroke(keyChar, keyCode, allModifiers, onKeyRelease);
+        return key;
+    }
+
+    /**
+     * Adds the mask.
+     * 
+     * @param mod the mod
+     * @param mask the mask
+     * 
+     * @return the int
+     */
+    private static int addMask(int mod, int mask) {
+        return ((mod & mask) != 0) ? (mod | mask) : mod;
+    }
+
+    /**
+     * return all (old & new) modifiers corresponding to.
+     * 
+     * @param mod old or new modifiers
+     * 
+     * @return old and new modifiers together
+     */
+    static int getAllModifiers(int mod) {
+        int allMod = mod;
+        int shift = (InputEvent.SHIFT_MASK | InputEvent.SHIFT_DOWN_MASK);
+        int ctrl = (InputEvent.CTRL_MASK | InputEvent.CTRL_DOWN_MASK);
+        int meta = (InputEvent.META_MASK | InputEvent.META_DOWN_MASK);
+        int alt = (InputEvent.ALT_MASK | InputEvent.ALT_DOWN_MASK);
+        int altGr = (InputEvent.ALT_GRAPH_MASK | InputEvent.ALT_GRAPH_DOWN_MASK);
+        // button modifiers are not converted between old & new
+
+        allMod = addMask(allMod, shift);
+        allMod = addMask(allMod, ctrl);
+        allMod = addMask(allMod, meta);
+        allMod = addMask(allMod, alt);
+        allMod = addMask(allMod, altGr);
+
+        return allMod;
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for parsed string.
+     * 
+     * The string must have the following syntax:
+     *<p>
+     * &lt;modifiers&gt;* (&lt;typedID&gt; | &lt;pressedReleasedID&gt;)
+     *<p>
+     * modifiers := shift | control | ctrl | meta | alt | altGraph
+     * <br> 
+     * typedID := typed <typedKey>
+     * <br>
+     * typedKey := string of length 1 giving the Unicode character.
+     * <br>
+     * pressedReleasedID := (pressed | released) <key>
+     * <br>
+     * key := KeyEvent key code name, i.e. the name following "VK_".
+     * <p>
+     * @param s the String which contains key stroke parameters.
+     * 
+     * @return the AWTKeyStroke for string.
+     * 
+     * @throws IllegalArgumentException if string has incorrect format or null.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(String s) {
+        if (s == null) {
+            // awt.65=null argument
+            throw new IllegalArgumentException(Messages.getString("awt.65")); //$NON-NLS-1$
+        }
+
+        StringTokenizer tokenizer = new StringTokenizer(s);
+
+        Boolean release = null;
+        int modifiers = 0;
+        int keyCode = KeyEvent.VK_UNDEFINED;
+        char keyChar = KeyEvent.CHAR_UNDEFINED;
+        boolean typed = false;
+        long modifier = 0;
+        String token = null;
+        do {
+            token = getNextToken(tokenizer);
+            modifier = parseModifier(token);
+            modifiers |= modifier;
+        } while (modifier > 0);
+
+        typed = parseTypedID(token);
+
+        if (typed) {
+            token = getNextToken(tokenizer);
+            keyChar = parseTypedKey(token);
+
+        }
+        if (keyChar == KeyEvent.CHAR_UNDEFINED) {
+            release = parsePressedReleasedID(token);
+            if (release != null) {
+                token = getNextToken(tokenizer);
+            }
+            keyCode = parseKey(token);
+        }
+        if (tokenizer.hasMoreTokens()) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+
+        return getAWTKeyStroke(keyChar, keyCode, modifiers,
+                               release == Boolean.TRUE);
+    }
+
+    /**
+     * Gets the next token.
+     * 
+     * @param tokenizer the tokenizer
+     * 
+     * @return the next token
+     */
+    private static String getNextToken(StringTokenizer tokenizer) {
+        try {
+            return tokenizer.nextToken();
+        } catch (NoSuchElementException exception) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Gets the key code.
+     * 
+     * @param s the s
+     * 
+     * @return the key code
+     */
+    static int getKeyCode(String s) {
+        try {
+            Field vk = KeyEvent.class.getField("VK_" + s); //$NON-NLS-1$
+            return vk.getInt(null);
+        } catch (Exception e) {
+            if (s.length() != 1) {
+                // awt.66=Invalid format
+                throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+            }
+            return KeyEvent.VK_UNDEFINED;
+        }
+    }
+
+    /**
+     * Gets an instance of the AWTKeyStroke for specified character.
+     * 
+     * @param keyChar the keyboard character value.
+     * 
+     * @return a AWTKeyStroke for specified character.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(char keyChar) {
+        return getAWTKeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false);
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for a given key code, set 
+     * of modifiers, and specified key released flag value.
+     * The key codes are defined in java.awt.event.KeyEvent class. 
+     * The set of modifiers is given as a bitwise combination 
+     * of masks taken from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+     * <li>java.awt.event.InputEvent.META_MASK</li>  
+     * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     *  <br>
+     *  
+     * @param keyCode the specified key code of keyboard.
+     * @param modifiers the bit set of modifiers.
+     * 
+     * @return the AWTKeyStroke.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers,
+                                               boolean onKeyRelease) {
+        return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode, modifiers,
+                               onKeyRelease);
+    }
+
+    /**
+     * Returns AWTKeyStroke for a specified character and set of modifiers. 
+     * The set of modifiers is given as a bitwise combination 
+     * of masks taken from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+     * <li>java.awt.event.InputEvent.META_MASK</li>  
+     * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     * 
+     * @param keyChar the Character object which represents keyboard character value.
+     * @param modifiers the bit set of modifiers.
+     * 
+     * @return the AWTKeyStroke object.
+     * 
+     * @throws IllegalArgumentException if keyChar value is null.
+     */
+    public static AWTKeyStroke getAWTKeyStroke(Character keyChar, int modifiers) {
+        if (keyChar == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "keyChar")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        return getAWTKeyStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED,
+                               modifiers, false);
+    }
+
+    /**
+     * Returns an instance of AWTKeyStroke for a specified key code and 
+     * set of modifiers.
+     * The key codes are defined in java.awt.event.KeyEvent class. 
+     * The set of modifiers is given as a bitwise combination 
+     * of masks taken from the following list:
+     * <ul>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.META_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_GRAPH_MASK</li>
+     * <li>java.awt.event.InputEvent.ALT_MASK</li>
+     * <li>java.awt.event.InputEvent.CTRL_MASK</li>
+     * <li>java.awt.event.InputEvent.META_MASK</li>  
+     * <li>java.awt.event.InputEvent.SHIFT_MASK</li>
+     * </ul>
+     *  
+     * @param keyCode the specified key code of keyboard.
+     * @param modifiers the bit set of modifiers.
+     * 
+     * @return the AWTKeyStroke
+     */
+    public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers) {
+        return getAWTKeyStroke(keyCode, modifiers, false);
+    }
+
+    /**
+     * Gets the AWTKeyStroke for a key event. This method obtains the key char 
+     * and key code from the specified key event.
+     * 
+     * @param anEvent the key event which identifies the desired AWTKeyStroke.
+     * 
+     * @return the AWTKeyStroke for the key event.
+     */
+    public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent anEvent) {
+        int id = anEvent.getID();
+        char undef = KeyEvent.CHAR_UNDEFINED;
+        char keyChar = (id == KeyEvent.KEY_TYPED ? anEvent.getKeyChar() :
+                                                   undef);
+        int keyCode = (keyChar == undef ? anEvent.getKeyCode() :
+                                          KeyEvent.VK_UNDEFINED);
+        return getAWTKeyStroke(keyChar, keyCode, anEvent.getModifiersEx(),
+                               id == KeyEvent.KEY_RELEASED);
+    }
+
+    /**
+     * Gets the key event type for the AWTKeyStroke object.
+     * 
+     * @return the key event type: KeyEvent.KEY_PRESSED, KeyEvent.KEY_TYPED, or KeyEvent.KEY_RELEASED
+     */
+    public final int getKeyEventType() {
+        if (keyCode == KeyEvent.VK_UNDEFINED) {
+            return KeyEvent.KEY_TYPED;
+        }
+        return (onKeyRelease ? KeyEvent.KEY_RELEASED : KeyEvent.KEY_PRESSED);
+    }
+
+    /**
+     * Retuns true if the key event is associated with the AWTKeyStroke is 
+     * KEY_RELEASED, overwise false.
+     * 
+     * @return true, if if the key event associated with the AWTKeyStroke is 
+     * KEY_RELEASED, overwise false.
+     */
+    public final boolean isOnKeyRelease() {
+        return onKeyRelease;
+    }
+
+    /**
+     * Read resolve.
+     * 
+     * @return the object
+     * 
+     * @throws ObjectStreamException the object stream exception
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        return getAWTKeyStroke(this.keyChar, this.keyCode,
+                               this.modifiers, this.onKeyRelease);
+    }
+
+    /**
+     * Register subclass.
+     * 
+     * @param subclass the subclass
+     */
+    protected static void registerSubclass(Class<?> subclass) {
+        //???AWT
+        /*
+        if (subclass == null) {
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "subclass")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if (! AWTKeyStroke.class.isAssignableFrom(subclass)) {
+            // awt.67=subclass is not derived from AWTKeyStroke
+            throw new ClassCastException(Messages.getString("awt.67")); //$NON-NLS-1$
+        }
+        try {
+            subConstructor = subclass.getDeclaredConstructor();
+            subConstructor.setAccessible(true);
+        } catch (SecurityException e) {
+            throw new RuntimeException(e);
+        } catch (NoSuchMethodException e) {
+            // awt.68=subclass could not be instantiated
+            throw new IllegalArgumentException(Messages.getString("awt.68")); //$NON-NLS-1$
+        }
+        cache.clear(); //flush the cache
+        */
+    }
+
+    /**
+     * Parses the modifier.
+     * 
+     * @param strMod the str mod
+     * 
+     * @return the long
+     */
+    private static long parseModifier(String strMod) {
+        long modifiers = 0l;
+        if (strMod.equals("shift")) { //$NON-NLS-1$
+            modifiers |= InputEvent.SHIFT_DOWN_MASK;
+        } else if (strMod.equals("control") || strMod.equals("ctrl")) { //$NON-NLS-1$ //$NON-NLS-2$
+            modifiers |= InputEvent.CTRL_DOWN_MASK;
+        } else if (strMod.equals("meta")) { //$NON-NLS-1$
+            modifiers |= InputEvent.META_DOWN_MASK;
+        } else if (strMod.equals("alt")) { //$NON-NLS-1$
+            modifiers |= InputEvent.ALT_DOWN_MASK;
+        } else if (strMod.equals("altGraph")) { //$NON-NLS-1$
+            modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
+        } else if (strMod.equals("button1")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON1_DOWN_MASK;
+        } else if (strMod.equals("button2")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON2_DOWN_MASK;
+        } else if (strMod.equals("button3")) { //$NON-NLS-1$
+            modifiers |= InputEvent.BUTTON3_DOWN_MASK;
+        }
+        return modifiers;
+    }
+
+    /**
+     * Parses the typed id.
+     * 
+     * @param strTyped the str typed
+     * 
+     * @return true, if successful
+     */
+    private static boolean parseTypedID(String strTyped) {
+        if (strTyped.equals("typed")) { //$NON-NLS-1$
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parses the typed key.
+     * 
+     * @param strChar the str char
+     * 
+     * @return the char
+     */
+    private static char parseTypedKey(String strChar) {
+        char keyChar = KeyEvent.CHAR_UNDEFINED;
+
+        if (strChar.length() != 1) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+        keyChar = strChar.charAt(0);
+        return keyChar;
+    }
+
+    /**
+     * Parses the pressed released id.
+     * 
+     * @param str the str
+     * 
+     * @return the boolean
+     */
+    private static Boolean parsePressedReleasedID(String str) {
+
+        if (str.equals("pressed")) { //$NON-NLS-1$
+            return Boolean.FALSE;
+        } else if (str.equals("released")) { //$NON-NLS-1$
+            return Boolean.TRUE;
+        }
+        return null;
+    }
+
+    /**
+     * Parses the key.
+     * 
+     * @param strCode the str code
+     * 
+     * @return the int
+     */
+    private static int parseKey(String strCode) {
+        int keyCode = KeyEvent.VK_UNDEFINED;
+
+        keyCode = getKeyCode(strCode);
+
+        if (keyCode == KeyEvent.VK_UNDEFINED) {
+            // awt.66=Invalid format
+            throw new IllegalArgumentException(Messages.getString("awt.66")); //$NON-NLS-1$
+        }
+        return keyCode;
+    }
+}
+
diff --git a/awt/java/awt/AWTListenerList.java b/awt/java/awt/AWTListenerList.java
new file mode 100644
index 0000000..3327d63
--- /dev/null
+++ b/awt/java/awt/AWTListenerList.java
@@ -0,0 +1,47 @@
+/*
+ *  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 java.awt;
+
+import java.util.EventListener;
+
+import org.apache.harmony.awt.ListenerList;
+
+final class AWTListenerList<T extends EventListener> extends ListenerList<T> {
+    private static final long serialVersionUID = -2622077171532840953L;
+
+    private final Component owner;
+    
+    AWTListenerList() {
+        super();
+        this.owner = null;
+    }
+
+    AWTListenerList(Component owner) {
+        super();
+        this.owner = owner;
+    }
+
+    @Override
+    public void addUserListener(T listener) {
+        super.addUserListener(listener);
+
+        if (owner != null) {
+            owner.deprecatedEventHandler = false;
+        }
+    }
+}
diff --git a/awt/java/awt/AWTPermission.java b/awt/java/awt/AWTPermission.java
new file mode 100644
index 0000000..25326ab
--- /dev/null
+++ b/awt/java/awt/AWTPermission.java
@@ -0,0 +1,54 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.security.BasicPermission;
+
+/**
+ * The AWTPermission specifies the name of the permission and the 
+ * corresponding action list.
+ */
+public final class AWTPermission extends BasicPermission {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8890392402588814465L;
+
+    /**
+     * Instantiates a new AWTPermission with defined name and actions.
+     * 
+     * @param name the name of a new AWTPermission. 
+     * @param actions the actions of a new AWTPermission.
+     */
+    public AWTPermission(String name, String actions) {
+        super(name, actions);
+    }
+
+    /**
+     * Instantiates a new AWT permission with the defined name.
+     * 
+     * @param name the name of a new AWTPermission. 
+     */
+    public AWTPermission(String name) {
+        super(name);
+    }
+
+}
+
diff --git a/awt/java/awt/ActiveEvent.java b/awt/java/awt/ActiveEvent.java
new file mode 100644
index 0000000..4133752
--- /dev/null
+++ b/awt/java/awt/ActiveEvent.java
@@ -0,0 +1,36 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * This interface defines events that know how to dispatch themselves. 
+ * Such event can be placed upon the event queue and its dispatch method 
+ * will be called when the event is dispatched.
+ */
+public interface ActiveEvent {
+
+    /**
+     * Dispatches the event to the listeners of the event's source, 
+     * or does whatever it is this event is supposed to do.
+     */
+    public void dispatch();
+
+}
diff --git a/awt/java/awt/Adjustable.java b/awt/java/awt/Adjustable.java
new file mode 100644
index 0000000..3241cad
--- /dev/null
+++ b/awt/java/awt/Adjustable.java
@@ -0,0 +1,156 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.AdjustmentListener;
+
+/**
+ * The Adjustable interface represents an adjustable numeric value 
+ * contained within a bounded range of values, such as the current 
+ * location in scrollable region or the value of a gauge.
+ */
+public interface Adjustable {
+
+    /** 
+     * The Constant HORIZONTAL indicates that the Adjustable's orientation 
+     * is horizontal. 
+     */
+    public static final int HORIZONTAL = 0;
+
+    /** 
+     * The Constant VERTICAL indicates that the Adjustable's orientation 
+     * is vertical. 
+     */
+    public static final int VERTICAL = 1;
+
+    /** 
+     * The Constant NO_ORIENTATION indicates that the Adjustable 
+     * has no orientation.
+     */
+    public static final int NO_ORIENTATION = 2;
+
+    /**
+     * Gets the value of the Adjustable.
+     * 
+     * @return the current value of the Adjustable.
+     */
+    public int getValue();
+
+    /**
+     * Sets the value to the Adjustable object.
+     * 
+     * @param a0 the new value of the Adjustable object. 
+     */
+    public void setValue(int a0);
+
+    /**
+     * Adds the AdjustmentListener to current Adjustment.
+     * 
+     * @param a0 the AdjustmentListener object.
+     */
+    public void addAdjustmentListener(AdjustmentListener a0);
+
+    /**
+     * Gets the block increment of the Adjustable.
+     * 
+     * @return the block increment of the Adjustable.
+     */
+    public int getBlockIncrement();
+
+    /**
+     * Gets the maximum value of the Adjustable.
+     * 
+     * @return the maximum value of the Adjustable.
+     */
+    public int getMaximum();
+
+    /**
+     * Gets the minimum value of the Adjustable.
+     * 
+     * @return the minimum value of the Adjustable. 
+     */
+    public int getMinimum();
+
+    /**
+     * Gets the orientation of the Adjustable.
+     * 
+     * @return the orientation of the Adjustable.
+     */
+    public int getOrientation();
+
+    /**
+     * Gets the unit increment of the Adjustable.
+     * 
+     * @return the unit increment of the Adjustable.
+     */
+    public int getUnitIncrement();
+
+    /**
+     * Gets the visible amount of the Adjustable.
+     * 
+     * @return the visible amount of the Adjustable.
+     */
+    public int getVisibleAmount();
+
+    /**
+     * Removes the adjustment listener of the Adjustable.
+     * 
+     * @param a0 the specified AdjustmentListener to be removed.
+     */
+    public void removeAdjustmentListener(AdjustmentListener a0);
+
+    /**
+     * Sets the block increment for the Adjustable.
+     * 
+     * @param a0 the new block increment.
+     */
+    public void setBlockIncrement(int a0);
+
+    /**
+     * Sets the maximum value of the Adjustable.
+     * 
+     * @param a0 the new maximum of the Adjustable.
+     */
+    public void setMaximum(int a0);
+
+    /**
+     * Sets the minimum value of the Adjustable.
+     * 
+     * @param a0 the new minimum of the Adjustable.
+     */
+    public void setMinimum(int a0);
+
+    /**
+     * Sets the unit increment of the Adjustable.
+     * 
+     * @param a0 the new unit increment of the Adjustable.
+     */
+    public void setUnitIncrement(int a0);
+
+    /**
+     * Sets the visible amount of the Adjustable.
+     * 
+     * @param a0 the new visible amount of the Adjustable.
+     */
+    public void setVisibleAmount(int a0);
+
+}
+
diff --git a/awt/java/awt/AlphaComposite.java b/awt/java/awt/AlphaComposite.java
new file mode 100644
index 0000000..d26753c
--- /dev/null
+++ b/awt/java/awt/AlphaComposite.java
@@ -0,0 +1,315 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.RenderingHints;
+import java.awt.image.ColorModel;
+
+import org.apache.harmony.awt.gl.ICompositeContext;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * The AlphaComposite class defines a basic alpha compositing rules for 
+ * combining source and destination colors to achieve blending and 
+ * transparency effects with graphics and images.
+ */
+public final class AlphaComposite implements Composite {
+
+    /** 
+     * The Constant CLEAR indicates that both the color and the alpha of 
+     * the destination are cleared (Porter-Duff Clear rule).
+     */
+    public static final int CLEAR = 1;
+
+    /** 
+     * The Constant SRC indicates that the source is copied to the destination 
+     * (Porter-Duff Source rule).
+     */
+    public static final int SRC = 2;
+
+    /** The Constant DST indicates that the destination is left untouched 
+     * (Porter-Duff Destination rule).
+     */
+    public static final int DST = 9;
+
+    /** 
+     * The Constant SRC_OVER indicates that the source is composited over 
+     * the destination (Porter-Duff Source Over Destination rule).
+     */
+    public static final int SRC_OVER = 3;
+
+    /**
+     * The Constant DST_OVER indicates that The destination is composited over 
+     * the source and the result replaces the destination 
+     * (Porter-Duff Destination Over Source rule).
+     */
+    public static final int DST_OVER = 4;
+
+    /**
+     * The Constant SRC_IN indicates that the part of the source lying 
+     * inside of the destination replaces the destination (Porter-Duff 
+     * Source In Destination rule).
+     */
+    public static final int SRC_IN = 5;
+
+    /** 
+     * The Constant DST_IN indicates that the part of the destination 
+     * lying inside of the source replaces the destination 
+     * (Porter-Duff Destination In Source rule).
+     */
+    public static final int DST_IN = 6;
+
+    /**
+     * The Constant SRC_OUT indicates that the part of the source lying 
+     * outside of the destination replaces the destination (Porter-Duff 
+     * Source Held Out By Destination rule).
+     */
+    public static final int SRC_OUT = 7;
+
+    /** 
+     * The Constant DST_OUT indicates that the part of the destination 
+     * lying outside of the source replaces the destination (Porter-Duff 
+     * Destination Held Out By Source rule).
+     */
+    public static final int DST_OUT = 8;
+
+    /** 
+     * The Constant SRC_ATOP indicates that the part of the source lying 
+     * inside of the destination is composited onto the destination 
+     * (Porter-Duff Source Atop Destination rule).
+     */
+    public static final int SRC_ATOP = 10;
+
+    /** 
+     * The Constant DST_ATOP indicates that the part of the destination 
+     * lying inside of the source is composited over the source and replaces 
+     * the destination (Porter-Duff Destination Atop Source rule).
+     */
+    public static final int DST_ATOP = 11;
+
+    /**
+     * The Constant XOR indicates that the part of the source that lies 
+     * outside of the destination is combined with the part of the destination 
+     * that lies outside of the source (Porter-Duff Source Xor Destination rule).
+     */
+    public static final int XOR = 12;
+
+    /** AlphaComposite object with the opaque CLEAR rule and an alpha of 1.0f. */
+    public static final AlphaComposite Clear = new AlphaComposite(CLEAR);
+
+    /** AlphaComposite object with the opaque SRC rule and an alpha of 1.0f. */
+    public static final AlphaComposite Src = new AlphaComposite(SRC);
+
+    /** AlphaComposite object with the opaque DST rule and an alpha of 1.0f. */
+    public static final AlphaComposite Dst = new AlphaComposite(DST);
+
+    /** AlphaComposite object with the opaque SRC_OVER rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcOver = new AlphaComposite(SRC_OVER);
+
+    /** AlphaComposite object with the opaque DST_OVER rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstOver = new AlphaComposite(DST_OVER);
+
+    /** AlphaComposite object with the opaque SRC_IN rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcIn = new AlphaComposite(SRC_IN);
+
+    /** AlphaComposite object with the opaque DST_IN rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstIn = new AlphaComposite(DST_IN);
+
+    /** AlphaComposite object with the opaque SRC_OUT rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcOut = new AlphaComposite(SRC_OUT);
+
+    /** AlphaComposite object with the opaque DST_OUT rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstOut = new AlphaComposite(DST_OUT);
+
+    /** AlphaComposite object with the opaque SRC_ATOP rule and an alpha of 1.0f. */
+    public static final AlphaComposite SrcAtop = new AlphaComposite(SRC_ATOP);
+
+    /** AlphaComposite object with the opaque DST_ATOP rule and an alpha of 1.0f. */
+    public static final AlphaComposite DstAtop = new AlphaComposite(DST_ATOP);
+
+    /** AlphaComposite object with the opaque XOR rule and an alpha of 1.0f. */
+    public static final AlphaComposite Xor = new AlphaComposite(XOR);
+
+    /** The rule. */
+    private int rule;
+    
+    /** The alpha. */
+    private float alpha;
+
+    /**
+     * Instantiates a new alpha composite.
+     * Creates a context for the compositing operation. The context contains state that is used in performing the compositing operation.
+     * 
+     * @param rule the rule
+     * @param alpha the alpha
+     */
+    private AlphaComposite(int rule, float alpha){
+        if(rule < CLEAR || rule > XOR) {
+            // awt.11D=Unknown rule
+            throw new IllegalArgumentException(Messages.getString("awt.11D")); //$NON-NLS-1$
+        }
+        if(alpha < 0.0f || alpha > 1.0f) {
+            // awt.11E=Wrong alpha value
+            throw new IllegalArgumentException(Messages.getString("awt.11E")); //$NON-NLS-1$
+        }
+
+        this.rule = rule;
+        this.alpha = alpha;
+    }
+
+    /**
+     * Instantiates a new alpha composite.
+     * 
+     * @param rule the rule
+     */
+    private AlphaComposite(int rule){
+        this(rule, 1.0f);
+    }
+
+    /**
+     * Creates a CompositeContext object with the specified source ColorModel,
+     * destination ColorModel and RenderingHints parameters for a composing 
+     * operation.
+     * 
+     * @param srcColorModel the source's ColorModel.
+     * @param dstColorModel the destination's ColorModel.
+     * @param hints the RenderingHints object.
+     * 
+     * @return the CompositeContext object.    
+     * 
+     * @see java.awt.Composite#createContext(java.awt.image.ColorModel, java.awt.image.ColorModel, java.awt.RenderingHints)
+     */
+    public CompositeContext createContext(ColorModel srcColorModel,
+            ColorModel dstColorModel, RenderingHints hints) {
+        return new ICompositeContext(this, srcColorModel, dstColorModel);
+    }
+
+    /**
+     * Compares the AlphaComposite object with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the AlphaComposite object is equal to the specified
+     * object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if(!(obj instanceof AlphaComposite)) {
+            return false;
+        }
+        AlphaComposite other = (AlphaComposite)obj;
+        return (this.rule == other.getRule() && this.alpha == other.getAlpha());
+    }
+
+    /**
+     * Returns the hash code of the AlphaComposite object.
+     * 
+     * @return the hash code of the AlphaComposite object.
+     */
+    @Override
+    public int hashCode() {
+        int hash = Float.floatToIntBits(alpha);
+        int tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= rule;
+        return hash;
+    }
+
+    /**
+     * Gets the compositing rule of this AlphaComposite object.
+     * 
+     * @return the compositing rule of this AlphaComposite object.
+     */
+    public int getRule() {
+        return rule;
+    }
+
+    /**
+     * Gets the alpha value of this AlphaComposite object; returns 1.0 if 
+     * this AlphaComposite object doesn't have alpha value.
+     * 
+     * @return the alpha value of this AlphaComposite object or 1.0 if 
+     * this AlphaComposite object doesn't have alpha value.
+     */
+    public float getAlpha() {
+        return alpha;
+    }
+
+    /**
+     * Gets the AlphaComposite instance with the specified rule and alpha value.
+     * 
+     * @param rule the compositing rule.
+     * @param alpha the alpha value.
+     * 
+     * @return AlphaComposite instance.
+     */
+    public static AlphaComposite getInstance(int rule, float alpha) {
+        if(alpha == 1.0f) {
+            return getInstance(rule);
+        }
+        return new AlphaComposite(rule, alpha);
+    }
+
+    /**
+     * Gets the AlphaComposite instance with the specified rule.
+     * 
+     * @param rule the compositing rule.
+     * 
+     * @return AlphaComposite instance.
+     */
+    public static AlphaComposite getInstance(int rule) {
+        switch(rule){
+        case CLEAR:
+            return Clear;
+        case SRC:
+            return Src;
+        case DST:
+            return Dst;
+        case SRC_OVER:
+            return SrcOver;
+        case DST_OVER:
+            return DstOver;
+        case SRC_IN:
+            return SrcIn;
+        case DST_IN:
+            return DstIn;
+        case SRC_OUT:
+            return SrcOut;
+        case DST_OUT:
+            return DstOut;
+        case SRC_ATOP:
+            return SrcAtop;
+        case DST_ATOP:
+            return DstAtop;
+        case XOR:
+            return Xor;
+        default:
+            // awt.11D=Unknown rule
+            throw new IllegalArgumentException(Messages.getString("awt.11D")); //$NON-NLS-1$
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/BasicStroke.java b/awt/java/awt/BasicStroke.java
new file mode 100644
index 0000000..955dc6b
--- /dev/null
+++ b/awt/java/awt/BasicStroke.java
@@ -0,0 +1,2204 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The BasicStroke class specifies a set of rendering attributes for the outlines 
+ * of graphics primitives. The BasicStroke attributes describe the shape of the 
+ * pen which draws the outline of a Shape and the decorations applied at the ends
+ * and joins of path segments of the Shape. The BasicStroke has the following
+ * rendering attributes:
+ * <p>
+ * <ul>
+ * <li> line width -the pen width which draws the outlines.</li>
+ * <li> end caps - indicates the decoration applied to the ends of unclosed 
+ * subpaths and dash segments. The BasicStroke defines three different decorations:
+ * CAP_BUTT, CAP_ROUND, and CAP_SQUARE.</li>
+ * <li>line joins - indicates the decoration applied at the intersection of 
+ * two path segments and at the intersection of the endpoints of a subpath.
+ * The BasicStroke defines three decorations: JOIN_BEVEL, JOIN_MITER, 
+ * and JOIN_ROUND.</li>
+ * <li>miter limit - the limit to trim a line join that has a JOIN_MITER 
+ * decoration.</li>
+ * <li>dash attributes - the definition of how to make a dash pattern by 
+ * alternating between opaque and transparent sections </li>
+ * </ul>
+ */
+public class BasicStroke implements Stroke {
+
+    /** 
+     * The Constant CAP_BUTT indicates the ends of unclosed subpaths 
+     * and dash segments have no added decoration.
+     */
+    public static final int CAP_BUTT = 0;
+    
+    /** 
+     * The Constant CAP_ROUND indicates the ends of unclosed subpaths 
+     * and dash segments have a round decoration.
+     */
+    public static final int CAP_ROUND = 1;
+    
+    /** 
+     * The Constant CAP_SQUARE indicates the ends of unclosed subpaths 
+     * and dash segments have a square projection.
+     */
+    public static final int CAP_SQUARE = 2;
+
+    /** 
+     * The Constant JOIN_MITER indicates that path segments are joined by 
+     * extending their outside edges until they meet.
+     */
+    public static final int JOIN_MITER = 0;
+    
+    /** 
+     * The Constant JOIN_ROUND indicates that path segments are joined by 
+     * rounding off the corner at a radius of half the line width.
+     */
+    public static final int JOIN_ROUND = 1;
+    
+    /** 
+     * The Constant JOIN_BEVEL indicates that path segments are joined by 
+     * connecting the outer corners of their wide outlines with 
+     * a straight segment.
+     */
+    public static final int JOIN_BEVEL = 2;
+    
+    /** Constants for calculating. */
+    static final int MAX_LEVEL = 20;        // Maximal deepness of curve subdivision
+    
+    /** The Constant CURVE_DELTA. */
+    static final double CURVE_DELTA = 2.0;  // Width tolerance
+    
+    /** The Constant CORNER_ANGLE. */
+    static final double CORNER_ANGLE = 4.0; // Minimum corner angle
+    
+    /** The Constant CORNER_ZERO. */
+    static final double CORNER_ZERO = 0.01; // Zero angle
+    
+    /** The Constant CUBIC_ARC. */
+    static final double CUBIC_ARC = 4.0 / 3.0 * (Math.sqrt(2.0) - 1);
+
+    /** Stroke width. */
+    float width;
+    
+    /** Stroke cap type. */
+    int cap;
+    
+    /** Stroke join type. */
+    int join;
+    
+    /** Stroke miter limit. */
+    float miterLimit;
+    
+    /** Stroke dashes array. */
+    float dash[];
+    
+    /** Stroke dash phase. */
+    float dashPhase;
+
+    /** The temporary pre-calculated values. */
+    double curveDelta;
+    
+    /** The corner delta. */
+    double cornerDelta;
+    
+    /** The zero delta. */
+    double zeroDelta;
+
+    /** The w2. */
+    double w2;
+    
+    /** The fmy. */
+    double fmx, fmy;
+    
+    /** The smy. */
+    double scx, scy, smx, smy;
+    
+    /** The cy. */
+    double mx, my, cx, cy;
+
+    /** The temporary indicators. */
+    boolean isMove;
+    
+    /** The is first. */
+    boolean isFirst;
+    
+    /** The check move. */
+    boolean checkMove;
+    
+    /** The temporary and destination work paths. */
+    BufferedPath dst, lp, rp, sp;
+    
+    /** Stroke dasher class. */
+    Dasher dasher;
+
+    /**
+     * Instantiates a new BasicStroke with default width, cap, join, limit,
+     * dash attributes parameters. The default parameters are a solid line of 
+     * width 1.0, CAP_SQUARE, JOIN_MITER, a miter limit of 10.0, null dash attributes,
+     * and a dash phase of 0.0f.
+     */
+    public BasicStroke() {
+        this(1.0f, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with the specified width,  
+     * caps, joins, limit, dash attributes, dash phase parameters.
+     * 
+     * @param width the width of BasikStroke.
+     * @param cap the end decoration of BasikStroke.
+     * @param join the join segments decoration.
+     * @param miterLimit the limit to trim the miter join.
+     * @param dash the array with the dashing pattern.
+     * @param dashPhase the offset to start the dashing pattern.
+     */
+    public BasicStroke(float width, int cap, int join, float miterLimit, float[] dash, float dashPhase) {
+        if (width < 0.0f) {
+            // awt.133=Negative width
+            throw new IllegalArgumentException(Messages.getString("awt.133")); //$NON-NLS-1$
+        }
+        if (cap != CAP_BUTT && cap != CAP_ROUND && cap != CAP_SQUARE) {
+            // awt.134=Illegal cap
+            throw new IllegalArgumentException(Messages.getString("awt.134")); //$NON-NLS-1$
+        }
+        if (join != JOIN_MITER && join != JOIN_ROUND && join != JOIN_BEVEL) {
+            // awt.135=Illegal join
+            throw new IllegalArgumentException(Messages.getString("awt.135")); //$NON-NLS-1$
+        }
+        if (join == JOIN_MITER && miterLimit < 1.0f) {
+            // awt.136=miterLimit less than 1.0f
+            throw new IllegalArgumentException(Messages.getString("awt.136")); //$NON-NLS-1$
+        }
+        if (dash != null) {
+            if (dashPhase < 0.0f) {
+                // awt.137=Negative dashPhase
+                throw new IllegalArgumentException(Messages.getString("awt.137")); //$NON-NLS-1$
+            }
+            if (dash.length == 0) {
+                // awt.138=Zero dash length
+                throw new IllegalArgumentException(Messages.getString("awt.138")); //$NON-NLS-1$
+            }
+            ZERO: {
+                for(int i = 0; i < dash.length; i++) {
+                    if (dash[i] < 0.0) {
+                        // awt.139=Negative dash[{0}]
+                        throw new IllegalArgumentException(Messages.getString("awt.139", i)); //$NON-NLS-1$
+                    }
+                    if (dash[i] > 0.0) {
+                        break ZERO;
+                    }
+                }
+                // awt.13A=All dash lengths zero
+                throw new IllegalArgumentException(Messages.getString("awt.13A")); //$NON-NLS-1$
+            }
+        }
+        this.width = width;
+        this.cap = cap;
+        this.join = join;
+        this.miterLimit = miterLimit;
+        this.dash = dash;
+        this.dashPhase = dashPhase;
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width, cap, join, limit
+     * and default dash attributes parameters. 
+     * 
+     * @param width the width of BasikStroke.
+     * @param cap the end decoration of BasikStroke.
+     * @param join the join segments decoration.
+     * @param miterLimit the limit to trim the miter join.
+     */
+    public BasicStroke(float width, int cap, int join, float miterLimit) {
+        this(width, cap, join, miterLimit, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width, cap, join
+     * and default limit and dash attributes parameters. 
+     * 
+     * @param width the width of BasikStroke.
+     * @param cap the end decoration of BasikStroke.
+     * @param join the join segments decoration.
+     */
+    public BasicStroke(float width, int cap, int join) {
+        this(width, cap, join, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Instantiates a new BasicStroke with specified width and default cap, join,
+     * limit, dash attributes parameters.
+     * 
+     * @param width the width of BasicStroke.
+     */
+    public BasicStroke(float width) {
+        this(width, CAP_SQUARE, JOIN_MITER, 10.0f, null, 0.0f);
+    }
+
+    /**
+     * Gets the line width of the BasicStroke.
+     * 
+     * @return the line width of the BasicStroke.
+     */
+    public float getLineWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the end cap style of the BasicStroke.
+     * 
+     * @return the end cap style of the BasicStroke.
+     */
+    public int getEndCap() {
+        return cap;
+    }
+
+    /**
+     * Gets the line join style of the BasicStroke.
+     * 
+     * @return the line join style of the BasicStroke.
+     */
+    public int getLineJoin() {
+        return join;
+    }
+
+    /**
+     * Gets the miter limit of the BasicStroke (the limit to trim the miter join).
+     * 
+     * @return the miter limit of the BasicStroke.
+     */
+    public float getMiterLimit() {
+        return miterLimit;
+    }
+
+    /**
+     * Gets the dash attributes array of the BasicStroke.
+     * 
+     * @return the dash attributes array of the BasicStroke.
+     */
+    public float[] getDashArray() {
+        return dash;
+    }
+
+    /**
+     * Gets the dash phase of the BasicStroke.
+     * 
+     * @return the dash phase of the BasicStroke.
+     */
+    public float getDashPhase() {
+        return dashPhase;
+    }
+
+    /**
+     * Returns hash code of this BasicStroke.
+     * 
+     * @return the hash code of this BasicStroke.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(width);
+        hash.append(cap);
+        hash.append(join);
+        hash.append(miterLimit);
+        if (dash != null) {
+            hash.append(dashPhase);
+            for (float element : dash) {
+                hash.append(element);
+            }
+        }
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this BasicStroke object with the specified Object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the Object is a BasicStroke with the same data
+     * values as this BasicStroke; false otherwise. 
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof BasicStroke) {
+            BasicStroke bs = (BasicStroke)obj;
+            return
+                bs.width == width &&
+                bs.cap == cap &&
+                bs.join == join &&
+                bs.miterLimit == miterLimit &&
+                bs.dashPhase == dashPhase &&
+                java.util.Arrays.equals(bs.dash, dash);
+        }
+        return false;
+    }
+
+    /**
+     * Calculates allowable curve derivation.
+     * 
+     * @param width the width
+     * 
+     * @return the curve delta
+     */
+    double getCurveDelta(double width) {
+        double a = width + CURVE_DELTA;
+        double cos = 1.0 - 2.0 * width * width / (a * a);
+        double sin = Math.sqrt(1.0 - cos * cos);
+        return Math.abs(sin / cos);
+    }
+
+    /**
+     * Calculates the value to detect a small angle.
+     * 
+     * @param width the width
+     * 
+     * @return the corner delta
+     */
+    double getCornerDelta(double width) {
+        return width * width * Math.sin(Math.PI * CORNER_ANGLE / 180.0);
+    }
+
+    /**
+     * Calculates value to detect a zero angle.
+     * 
+     * @param width the width
+     * 
+     * @return the zero delta
+     */
+    double getZeroDelta(double width) {
+        return width * width * Math.sin(Math.PI * CORNER_ZERO / 180.0);
+    }
+
+    /**
+     * Creates a Shape from the outline of the specified shape 
+     * drawn with this BasicStroke.
+     * 
+     * @param s the specified Shape to be stroked.
+     * 
+     * @return the Shape of the stroked outline.
+     * 
+     * @see java.awt.Stroke#createStrokedShape(java.awt.Shape)
+     */
+    public Shape createStrokedShape(Shape s) {
+        w2 = width / 2.0;
+        curveDelta = getCurveDelta(w2);
+        cornerDelta = getCornerDelta(w2);
+        zeroDelta = getZeroDelta(w2);
+
+        dst = new BufferedPath();
+        lp = new BufferedPath();
+        rp = new BufferedPath();
+
+        if (dash == null) {
+            createSolidShape(s.getPathIterator(null));
+        } else {
+            createDashedShape(s.getPathIterator(null));
+        }
+
+        return dst.createGeneralPath();
+    }
+
+    /**
+     * Generates a shape with a solid (not dashed) outline.
+     * 
+     * @param p - the PathIterator of source shape
+     */
+    void createSolidShape(PathIterator p) {
+        double coords[] = new double[6];
+        mx = my = cx = cy = 0.0;
+        isMove = false;
+        isFirst = false;
+        checkMove = true;
+        boolean isClosed = true;
+
+        while(!p.isDone()) {
+            switch(p.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (!isClosed) {
+                    closeSolidShape();
+                }
+                rp.clean();
+                mx = cx = coords[0];
+                my = cy = coords[1];
+                isMove = true;
+                isClosed = false;
+                break;
+            case PathIterator.SEG_LINETO:
+                addLine(cx, cy, cx = coords[0], cy = coords[1], true);
+                break;
+            case PathIterator.SEG_QUADTO:
+                addQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3]);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                addCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5]);
+                break;
+            case PathIterator.SEG_CLOSE:
+                addLine(cx, cy, mx, my, false);
+                addJoin(lp, mx, my, lp.xMove, lp.yMove, true);
+                addJoin(rp, mx, my, rp.xMove, rp.yMove, false);
+                lp.closePath();
+                rp.closePath();
+                lp.appendReverse(rp);
+                isClosed = true;
+                break;
+            }
+            p.next();
+        }
+        if (!isClosed) {
+            closeSolidShape();
+        }
+
+        dst = lp;
+    }
+
+    /**
+     * Closes solid shape path.
+     */
+    void closeSolidShape() {
+        addCap(lp, cx, cy, rp.xLast, rp.yLast);
+        lp.combine(rp);
+        addCap(lp, mx, my, lp.xMove, lp.yMove);
+        lp.closePath();
+    }
+
+    /**
+     * Generates dashed stroked shape.
+     * 
+     * @param p - the PathIterator of source shape
+     */
+    void createDashedShape(PathIterator p) {
+        double coords[] = new double[6];
+        mx = my = cx = cy = 0.0;
+        smx = smy = scx = scy = 0.0;
+        isMove = false;
+        checkMove = false;
+        boolean isClosed = true;
+
+        while(!p.isDone()) {
+            switch(p.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+
+                if (!isClosed) {
+                    closeDashedShape();
+                }
+
+                dasher = new Dasher(dash, dashPhase);
+                lp.clean();
+                rp.clean();
+                sp = null;
+                isFirst = true;
+                isMove = true;
+                isClosed = false;
+                mx = cx = coords[0];
+                my = cy = coords[1];
+                break;
+            case PathIterator.SEG_LINETO:
+                addDashLine(cx, cy, cx = coords[0], cy = coords[1]);
+                break;
+            case PathIterator.SEG_QUADTO:
+                addDashQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3]);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                addDashCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5]);
+                break;
+            case PathIterator.SEG_CLOSE:
+                addDashLine(cx, cy, cx = mx, cy = my);
+
+                if (dasher.isConnected()) {
+                    // Connect current and head segments
+                    addJoin(lp, fmx, fmy, sp.xMove, sp.yMove, true);
+                    lp.join(sp);
+                    addJoin(lp, fmx, fmy, rp.xLast, rp.yLast, true);
+                    lp.combine(rp);
+                    addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                    lp.closePath();
+                    dst.append(lp);
+                    sp = null;
+                } else {
+                    closeDashedShape();
+                }
+
+                isClosed = true;
+                break;
+            }
+            p.next();
+        }
+
+        if (!isClosed) {
+            closeDashedShape();
+        }
+
+    }
+
+    /**
+     * Closes dashed shape path.
+     */
+    void closeDashedShape() {
+        // Add head segment
+        if (sp != null) {
+            addCap(sp, fmx, fmy, sp.xMove, sp.yMove);
+            sp.closePath();
+            dst.append(sp);
+        }
+        if (lp.typeSize > 0) {
+            // Close current segment
+            if (!dasher.isClosed()) {
+                addCap(lp, scx, scy, rp.xLast, rp.yLast);
+                lp.combine(rp);
+                addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                lp.closePath();
+            }
+            dst.append(lp);
+        }
+    }
+
+    /**
+     * Adds cap to the work path.
+     * 
+     * @param p - the BufferedPath object of work path
+     * @param x0 - the x coordinate of the source path
+     * @param y0 - the y coordinate on the source path
+     * @param x2 - the x coordinate of the next point on the work path
+     * @param y2 - the y coordinate of the next point on the work path
+     */
+    void addCap(BufferedPath p, double x0, double y0, double x2, double y2) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+
+        switch(cap) {
+        case CAP_BUTT:
+            p.lineTo(x2, y2);
+            break;
+        case CAP_ROUND:
+            double mx = x10 * CUBIC_ARC;
+            double my = y10 * CUBIC_ARC;
+
+            double x3 = x0 + y10;
+            double y3 = y0 - x10;
+
+            x10 *= CUBIC_ARC;
+            y10 *= CUBIC_ARC;
+            x20 *= CUBIC_ARC;
+            y20 *= CUBIC_ARC;
+
+            p.cubicTo(x1 + y10, y1 - x10, x3 + mx, y3 + my, x3, y3);
+            p.cubicTo(x3 - mx, y3 - my, x2 - y20, y2 + x20, x2, y2);
+            break;
+        case CAP_SQUARE:
+            p.lineTo(x1 + y10, y1 - x10);
+            p.lineTo(x2 - y20, y2 + x20);
+            p.lineTo(x2, y2);
+            break;
+        }
+    }
+
+    /**
+     * Adds bevel and miter join to the work path.
+     * 
+     * @param p - the BufferedPath object of work path
+     * @param x0 - the x coordinate of the source path
+     * @param y0 - the y coordinate on the source path
+     * @param x2 - the x coordinate of the next point on the work path
+     * @param y2 - the y coordinate of the next point on the work path
+     * @param isLeft - the orientation of work path, true if work path lies to the left from source path, false otherwise
+     */
+    void addJoin(BufferedPath p, double x0, double y0, double x2, double y2, boolean isLeft) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+        double sin0 = x10 * y20 - y10 * x20;
+
+        // Small corner
+        if (-cornerDelta < sin0 && sin0 < cornerDelta) {
+            double cos0 = x10 * x20 + y10 * y20;
+            if (cos0 > 0.0) {
+                // if zero corner do nothing
+                if (-zeroDelta > sin0 || sin0 > zeroDelta) {
+                    double x3 = x0 + w2 * w2 * (y20 - y10) / sin0;
+                    double y3 = y0 + w2 * w2 * (x10 - x20) / sin0;
+                    p.setLast(x3, y3);
+                }
+                return;
+            }
+            // Zero corner
+            if (-zeroDelta < sin0 && sin0 < zeroDelta) {
+                p.lineTo(x2, y2);
+            }
+            return;
+        }
+
+        if (isLeft ^ (sin0 < 0.0)) {
+            // Twisted corner
+            p.lineTo(x0, y0);
+            p.lineTo(x2, y2);
+        } else {
+            switch(join) {
+            case JOIN_BEVEL:
+                p.lineTo(x2, y2);
+                break;
+            case JOIN_MITER:
+                double s1 = x1 * x10 + y1 * y10;
+                double s2 = x2 * x20 + y2 * y20;
+                double x3 = (s1 * y20 - s2 * y10) / sin0;
+                double y3 = (s2 * x10 - s1 * x20) / sin0;
+                double x30 = x3 - x0;
+                double y30 = y3 - y0;
+                double miterLength = Math.sqrt(x30 * x30 + y30 * y30);
+                if (miterLength < miterLimit * w2) {
+                    p.lineTo(x3, y3);
+                }
+                p.lineTo(x2, y2);
+                break;
+            case JOIN_ROUND:
+                addRoundJoin(p, x0, y0, x2, y2, isLeft);
+                break;
+            }
+        }
+    }
+
+    /**
+     * Adds round join to the work path.
+     * 
+     * @param p - the BufferedPath object of work path
+     * @param x0 - the x coordinate of the source path
+     * @param y0 - the y coordinate on the source path
+     * @param x2 - the x coordinate of the next point on the work path
+     * @param y2 - the y coordinate of the next point on the work path
+     * @param isLeft - the orientation of work path, true if work path lies to the left from source path, false otherwise
+     */
+    void addRoundJoin(BufferedPath p, double x0, double y0, double x2, double y2, boolean isLeft) {
+        double x1 = p.xLast;
+        double y1 = p.yLast;
+        double x10 = x1 - x0;
+        double y10 = y1 - y0;
+        double x20 = x2 - x0;
+        double y20 = y2 - y0;
+
+        double x30 = x10 + x20;
+        double y30 = y10 + y20;
+
+        double l30 = Math.sqrt(x30 * x30 + y30 * y30);
+
+        if (l30 < 1E-5) {
+            p.lineTo(x2, y2);
+            return;
+        }
+
+        double w = w2 / l30;
+
+        x30 *= w;
+        y30 *= w;
+
+        double x3 = x0 + x30;
+        double y3 = y0 + y30;
+
+        double cos = x10 * x20 + y10 * y20;
+        double a = Math.acos(cos / (w2 * w2));
+        if (cos >= 0.0) {
+            double k = 4.0 / 3.0 * Math.tan(a / 4.0);
+            if (isLeft) {
+                k = -k;
+            }
+
+            x10 *= k;
+            y10 *= k;
+            x20 *= k;
+            y20 *= k;
+
+            p.cubicTo(x1 - y10, y1 + x10, x2 + y20, y2 - x20, x2, y2);
+        } else {
+            double k = 4.0 / 3.0 * Math.tan(a / 8.0);
+            if (isLeft) {
+                k = -k;
+            }
+
+            x10 *= k;
+            y10 *= k;
+            x20 *= k;
+            y20 *= k;
+            x30 *= k;
+            y30 *= k;
+
+            p.cubicTo(x1 - y10, y1 + x10, x3 + y30, y3 - x30, x3, y3);
+            p.cubicTo(x3 - y30, y3 + x30, x2 + y20, y2 - x20, x2, y2);
+        }
+
+    }
+
+    /**
+     * Adds solid line segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the start line point
+     * @param y1 - the y coordinate of the start line point
+     * @param x2 - the x coordinate of the end line point
+     * @param y2 - the y coordinate of the end line point
+     * @param zero - if true it's allowable to add zero length line segment
+     */
+    void addLine(double x1, double y1, double x2, double y2, boolean zero) {
+        double dx = x2 - x1;
+        double dy = y2 - y1;
+
+        if (dx == 0.0 && dy == 0.0) {
+            if (!zero) {
+                return;
+            }
+            dx = w2;
+            dy = 0;
+        } else {
+            double w = w2 / Math.sqrt(dx * dx + dy * dy);
+            dx *= w;
+            dy *= w;
+        }
+
+        double lx1 = x1 - dy;
+        double ly1 = y1 + dx;
+        double rx1 = x1 + dy;
+        double ry1 = y1 - dx;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        lp.lineTo(x2 - dy, y2 + dx);
+        rp.lineTo(x2 + dy, y2 - dx);
+    }
+
+    /**
+     * Adds solid quad segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     */
+    void addQuad(double x1, double y1, double x2, double y2, double x3, double y3) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+
+        if (l21 == 0.0 && l23 == 0.0) {
+            addLine(x1, y1, x3, y3, false);
+            return;
+        }
+
+        if (l21 == 0.0) {
+            addLine(x2, y2, x3, y3, false);
+            return;
+        }
+
+        if (l23 == 0.0) {
+            addLine(x1, y1, x2, y2, false);
+            return;
+        }
+
+        double w;
+        w = w2 / l21;
+        double mx1 = - y21 * w;
+        double my1 =   x21 * w;
+        w = w2 / l23;
+        double mx3 =   y23 * w;
+        double my3 = - x23 * w;
+
+        double lx1 = x1 + mx1;
+        double ly1 = y1 + my1;
+        double rx1 = x1 - mx1;
+        double ry1 = y1 - my1;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        if (x21 * y23 - y21 * x23 == 0.0) {
+            // On line curve
+            if (x21 * x23 + y21 * y23 > 0.0) {
+                // Twisted curve
+                if (l21 == l23) {
+                    double px = x1 + (x21 + x23) / 4.0;
+                    double py = y1 + (y21 + y23) / 4.0;
+                    lp.lineTo(px + mx1, py + my1);
+                    rp.lineTo(px - mx1, py - my1);
+                    lp.lineTo(px - mx1, py - my1);
+                    rp.lineTo(px + mx1, py + my1);
+                    lp.lineTo(x3 - mx1, y3 - my1);
+                    rp.lineTo(x3 + mx1, y3 + my1);
+                } else {
+                    double px1, py1;
+                    double k = l21 / (l21 + l23);
+                    double px = x1 + (x21 + x23) * k * k;
+                    double py = y1 + (y21 + y23) * k * k;
+                    px1 = (x1 + px) / 2.0;
+                    py1 = (y1 + py) / 2.0;
+                    lp.quadTo(px1 + mx1, py1 + my1, px + mx1, py + my1);
+                    rp.quadTo(px1 - mx1, py1 - my1, px - mx1, py - my1);
+                    lp.lineTo(px - mx1, py - my1);
+                    rp.lineTo(px + mx1, py + my1);
+                    px1 = (x3 + px) / 2.0;
+                    py1 = (y3 + py) / 2.0;
+                    lp.quadTo(px1 - mx1, py1 - my1, x3 - mx1, y3 - my1);
+                    rp.quadTo(px1 + mx1, py1 + my1, x3 + mx1, y3 + my1);
+                }
+            } else {
+                // Simple curve
+                lp.quadTo(x2 + mx1, y2 + my1, x3 + mx3, y3 + my3);
+                rp.quadTo(x2 - mx1, y2 - my1, x3 - mx3, y3 - my3);
+            }
+        } else {
+            addSubQuad(x1, y1, x2, y2, x3, y3, 0);
+        }
+    }
+
+    /**
+     * Subdivides solid quad curve to make outline for source quad segment and adds it to work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param level - the maximum level of subdivision deepness
+     */
+    void addSubQuad(double x1, double y1, double x2, double y2, double x3, double y3, int level) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double cos = x21 * x23 + y21 * y23;
+        double sin = x21 * y23 - y21 * x23;
+
+        if (level < MAX_LEVEL && (cos >= 0.0 || (Math.abs(sin / cos) > curveDelta))) {
+            double c1x = (x2 + x1) / 2.0;
+            double c1y = (y2 + y1) / 2.0;
+            double c2x = (x2 + x3) / 2.0;
+            double c2y = (y2 + y3) / 2.0;
+            double c3x = (c1x + c2x) / 2.0;
+            double c3y = (c1y + c2y) / 2.0;
+            addSubQuad(x1, y1, c1x, c1y, c3x, c3y, level + 1);
+            addSubQuad(c3x, c3y, c2x, c2y, x3, y3, level + 1);
+        } else {
+            double w;
+            double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+            double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+            w = w2 / sin;
+            double mx2 = (x21 * l23 + x23 * l21) * w;
+            double my2 = (y21 * l23 + y23 * l21) * w;
+            w = w2 / l23;
+            double mx3 =   y23 * w;
+            double my3 = - x23 * w;
+            lp.quadTo(x2 + mx2, y2 + my2, x3 + mx3, y3 + my3);
+            rp.quadTo(x2 - mx2, y2 - my2, x3 - mx3, y3 - my3);
+        }
+    }
+
+    /**
+     * Adds solid cubic segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param x4 - the x coordinate of the fours control point
+     * @param y4 - the y coordinate of the fours control point
+     */
+    void addCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+        double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+        // All edges are zero
+        if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
+            addLine(x1, y1, x4, y4, false);
+            return;
+        }
+
+        // One zero edge
+        if (l12 == 0.0 && l23 == 0.0) {
+            addLine(x3, y3, x4, y4, false);
+            return;
+        }
+
+        if (l23 == 0.0 && l34 == 0.0) {
+            addLine(x1, y1, x2, y2, false);
+            return;
+        }
+
+        if (l12 == 0.0 && l34 == 0.0) {
+            addLine(x2, y2, x3, y3, false);
+            return;
+        }
+
+        double w, mx1, my1, mx4, my4;
+        boolean onLine;
+
+        if (l12 == 0.0) {
+            w = w2 / l23;
+            mx1 =   y23 * w;
+            my1 = - x23 * w;
+            w = w2 / l34;
+            mx4 =   y34 * w;
+            my4 = - x34 * w;
+            onLine = - x23 * y34 + y23 * x34 == 0.0; // sin3
+        } else
+        if (l34 == 0.0) {
+            w = w2 / l12;
+            mx1 =   y12 * w;
+            my1 = - x12 * w;
+            w = w2 / l23;
+            mx4 =   y23 * w;
+            my4 = - x23 * w;
+            onLine = - x12 * y23 + y12 * x23 == 0.0; // sin2
+        } else {
+            w = w2 / l12;
+            mx1 =   y12 * w;
+            my1 = - x12 * w;
+            w = w2 / l34;
+            mx4 =   y34 * w;
+            my4 = - x34 * w;
+            if (l23 == 0.0) {
+                onLine = - x12 * y34 + y12 * x34 == 0.0;
+            } else {
+                onLine =
+                    - x12 * y34 + y12 * x34 == 0.0 &&
+                    - x12 * y23 + y12 * x23 == 0.0 && // sin2
+                    - x23 * y34 + y23 * x34 == 0.0;   // sin3
+            }
+        }
+
+        double lx1 = x1 + mx1;
+        double ly1 = y1 + my1;
+        double rx1 = x1 - mx1;
+        double ry1 = y1 - my1;
+
+        if (checkMove) {
+            if (isMove) {
+                isMove = false;
+                lp.moveTo(lx1, ly1);
+                rp.moveTo(rx1, ry1);
+            } else {
+                addJoin(lp, x1, y1, lx1, ly1, true);
+                addJoin(rp, x1, y1, rx1, ry1, false);
+            }
+        }
+
+        if (onLine) {
+            if ((x1 == x2 && y1 < y2) || x1 < x2) {
+                l12 = -l12;
+            }
+            if ((x2 == x3 && y2 < y3) || x2 < x3) {
+                l23 = -l23;
+            }
+            if ((x3 == x4 && y3 < y4) || x3 < x4) {
+                l34 = -l34;
+            }
+            double d = l23 * l23 - l12 * l34;
+            double roots[] = new double[3];
+            int rc = 0;
+            if (d == 0.0) {
+                double t = (l12 - l23) / (l12 + l34 - l23 - l23);
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+            } else
+            if (d > 0.0) {
+                d = Math.sqrt(d);
+                double z = l12 + l34 - l23 - l23;
+                double t;
+                t = (l12 - l23 + d) / z;
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+                t = (l12 - l23 - d) / z;
+                if (0.0 < t && t < 1.0) {
+                    roots[rc++] = t;
+                }
+            }
+
+            if (rc > 0) {
+                // Sort roots
+                if (rc == 2 && roots[0] > roots[1]) {
+                    double tmp = roots[0];
+                    roots[0] = roots[1];
+                    roots[1] = tmp;
+                }
+                roots[rc++] = 1.0;
+
+                double ax = - x34 - x12 + x23 + x23;
+                double ay = - y34 - y12 + y23 + y23;
+                double bx = 3.0 * (- x23 + x12);
+                double by = 3.0 * (- y23 + y12);
+                double cx = 3.0 * (- x12);
+                double cy = 3.0 * (- y12);
+                double xPrev = x1;
+                double yPrev = y1;
+                for(int i = 0; i < rc; i++) {
+                    double t = roots[i];
+                    double px = t * (t * (t * ax + bx) + cx) + x1;
+                    double py = t * (t * (t * ay + by) + cy) + y1;
+                    double px1 = (xPrev + px) / 2.0;
+                    double py1 = (yPrev + py) / 2.0;
+                    lp.cubicTo(px1 + mx1, py1 + my1, px1 + mx1, py1 + my1, px + mx1, py + my1);
+                    rp.cubicTo(px1 - mx1, py1 - my1, px1 - mx1, py1 - my1, px - mx1, py - my1);
+                    if (i < rc - 1) {
+                        lp.lineTo(px - mx1, py - my1);
+                        rp.lineTo(px + mx1, py + my1);
+                    }
+                    xPrev = px;
+                    yPrev = py;
+                    mx1 = - mx1;
+                    my1 = - my1;
+                }
+            } else {
+                lp.cubicTo(x2 + mx1, y2 + my1, x3 + mx4, y3 + my4, x4 + mx4, y4 + my4);
+                rp.cubicTo(x2 - mx1, y2 - my1, x3 - mx4, y3 - my4, x4 - mx4, y4 - my4);
+            }
+        } else {
+            addSubCubic(x1, y1, x2, y2, x3, y3, x4, y4, 0);
+        }
+    }
+
+    /**
+     * Subdivides solid cubic curve to make outline for source quad segment and adds it to work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param x4 - the x coordinate of the fours control point
+     * @param y4 - the y coordinate of the fours control point
+     * @param level - the maximum level of subdivision deepness
+     */
+    void addSubCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, int level) {
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double cos2 = - x12 * x23 - y12 * y23;
+        double cos3 = - x23 * x34 - y23 * y34;
+        double sin2 = - x12 * y23 + y12 * x23;
+        double sin3 = - x23 * y34 + y23 * x34;
+        double sin0 = - x12 * y34 + y12 * x34;
+        double cos0 = - x12 * x34 - y12 * y34;
+
+        if (level < MAX_LEVEL && (sin2 != 0.0 || sin3 != 0.0 || sin0 != 0.0) &&
+            (cos2 >= 0.0 || cos3 >= 0.0 || cos0 >= 0.0 ||
+            (Math.abs(sin2 / cos2) > curveDelta) ||
+            (Math.abs(sin3 / cos3) > curveDelta) ||
+            (Math.abs(sin0 / cos0) > curveDelta)))
+        {
+            double cx = (x2 + x3) / 2.0;
+            double cy = (y2 + y3) / 2.0;
+            double lx2 = (x2 + x1) / 2.0;
+            double ly2 = (y2 + y1) / 2.0;
+            double rx3 = (x3 + x4) / 2.0;
+            double ry3 = (y3 + y4) / 2.0;
+            double lx3 = (cx + lx2) / 2.0;
+            double ly3 = (cy + ly2) / 2.0;
+            double rx2 = (cx + rx3) / 2.0;
+            double ry2 = (cy + ry3) / 2.0;
+            cx = (lx3 + rx2) / 2.0;
+            cy = (ly3 + ry2) / 2.0;
+            addSubCubic(x1, y1, lx2, ly2, lx3, ly3, cx, cy, level + 1);
+            addSubCubic(cx, cy, rx2, ry2, rx3, ry3, x4, y4, level + 1);
+        } else {
+            double w, mx1, my1, mx2, my2, mx3, my3, mx4, my4;
+            double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+            double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+            double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+            if (l12 == 0.0) {
+                w = w2 / l23;
+                mx1 =   y23 * w;
+                my1 = - x23 * w;
+                w = w2 / l34;
+                mx4 =   y34 * w;
+                my4 = - x34 * w;
+            } else
+            if (l34 == 0.0) {
+                w = w2 / l12;
+                mx1 =   y12 * w;
+                my1 = - x12 * w;
+                w = w2 / l23;
+                mx4 =   y23 * w;
+                my4 = - x23 * w;
+            } else {
+                // Common case
+                w = w2 / l12;
+                mx1 =   y12 * w;
+                my1 = - x12 * w;
+                w = w2 / l34;
+                mx4 =   y34 * w;
+                my4 = - x34 * w;
+            }
+
+            if (sin2 == 0.0) {
+                mx2 = mx1;
+                my2 = my1;
+            } else {
+                w = w2 / sin2;
+                mx2 = -(x12 * l23 - x23 * l12) * w;
+                my2 = -(y12 * l23 - y23 * l12) * w;
+            }
+            if (sin3 == 0.0) {
+                mx3 = mx4;
+                my3 = my4;
+            } else {
+                w = w2 / sin3;
+                mx3 = -(x23 * l34 - x34 * l23) * w;
+                my3 = -(y23 * l34 - y34 * l23) * w;
+            }
+
+            lp.cubicTo(x2 + mx2, y2 + my2, x3 + mx3, y3 + my3, x4 + mx4, y4 + my4);
+            rp.cubicTo(x2 - mx2, y2 - my2, x3 - mx3, y3 - my3, x4 - mx4, y4 - my4);
+        }
+    }
+
+    /**
+     * Adds dashed line segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the start line point
+     * @param y1 - the y coordinate of the start line point
+     * @param x2 - the x coordinate of the end line point
+     * @param y2 - the y coordinate of the end line point
+     */
+    void addDashLine(double x1, double y1, double x2, double y2) {
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+
+        if (l21 == 0.0) {
+            return;
+        }
+
+        double px1, py1;
+        px1 = py1 = 0.0;
+        double w = w2 / l21;
+        double mx = - y21 * w;
+        double my =   x21 * w;
+
+        dasher.init(new DashIterator.Line(l21));
+
+        while(!dasher.eof()) {
+            double t = dasher.getValue();
+            scx = x1 + t * x21;
+            scy = y1 + t * y21;
+
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                double lx1 = px1 + mx;
+                double ly1 = py1 + my;
+                double rx1 = px1 - mx;
+                double ry1 = py1 - my;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else
+                if (dasher.isContinue()) {
+                    double px2 = scx;
+                    double py2 = scy;
+                    lp.lineTo(px2 + mx, py2 + my);
+                    rp.lineTo(px2 - mx, py2 - my);
+                    if (dasher.close) {
+                        addCap(lp, px2, py2, rp.xLast, rp.yLast);
+                        lp.combine(rp);
+                        if (isFirst) {
+                            isFirst = false;
+                            fmx = smx;
+                            fmy = smy;
+                            sp = lp;
+                            lp = new BufferedPath();
+                        } else {
+                            addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                            lp.closePath();
+                        }
+                        isMove = true;
+                    }
+                }
+
+            dasher.next();
+        }
+    }
+
+    /**
+     * Adds dashed quad segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     */
+    void addDashQuad(double x1, double y1, double x2, double y2, double x3, double y3) {
+
+        double x21 = x2 - x1;
+        double y21 = y2 - y1;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+
+        double l21 = Math.sqrt(x21 * x21 + y21 * y21);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+
+        if (l21 == 0.0 && l23 == 0.0) {
+            return;
+        }
+
+        if (l21 == 0.0) {
+            addDashLine(x2, y2, x3, y3);
+            return;
+        }
+
+        if (l23 == 0.0) {
+            addDashLine(x1, y1, x2, y2);
+            return;
+        }
+
+        double ax = x1 + x3 - x2 - x2;
+        double ay = y1 + y3 - y2 - y2;
+        double bx = x2 - x1;
+        double by = y2 - y1;
+        double cx = x1;
+        double cy = y1;
+
+        double px1, py1, dx1, dy1;
+        px1 = py1 = dx1 = dy1 = 0.0;
+        double prev = 0.0;
+
+        dasher.init(new DashIterator.Quad(x1, y1, x2, y2, x3, y3));
+
+        while(!dasher.eof()) {
+            double t = dasher.getValue();
+            double dx = t * ax + bx;
+            double dy = t * ay + by;
+            scx = t * (dx + bx) + cx; // t^2 * ax + 2.0 * t * bx + cx
+            scy = t * (dy + by) + cy; // t^2 * ay + 2.0 * t * by + cy
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                dx1 = dx;
+                dy1 = dy;
+                double w = w2 / Math.sqrt(dx1 * dx1 + dy1 * dy1);
+                double mx1 = - dy1 * w;
+                double my1 =   dx1 * w;
+                double lx1 = px1 + mx1;
+                double ly1 = py1 + my1;
+                double rx1 = px1 - mx1;
+                double ry1 = py1 - my1;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else 
+                if (dasher.isContinue()) {
+                    double px3 = scx;
+                    double py3 = scy;
+                    double sx = x2 - x23 * prev;
+                    double sy = y2 - y23 * prev;
+                    double t2 = (t - prev) / (1 - prev);
+                    double px2 = px1 + (sx - px1) * t2;
+                    double py2 = py1 + (sy - py1) * t2;
+
+                    addQuad(px1, py1, px2, py2, px3, py3);
+                    if (dasher.isClosed()) {
+                        addCap(lp, px3, py3, rp.xLast, rp.yLast);
+                        lp.combine(rp);
+                        if (isFirst) {
+                            isFirst = false;
+                            fmx = smx;
+                            fmy = smy;
+                            sp = lp;
+                            lp = new BufferedPath();
+                        } else {
+                            addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                            lp.closePath();
+                        }
+                        isMove = true;
+                    }
+                }
+
+            prev = t;
+            dasher.next();
+        }
+    }
+
+    /**
+     * Adds dashed cubic segment to the work path.
+     * 
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param x3 - the x coordinate of the third control point
+     * @param y3 - the y coordinate of the third control point
+     * @param x4 - the x coordinate of the fours control point
+     * @param y4 - the y coordinate of the fours control point
+     */
+    void addDashCubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
+
+        double x12 = x1 - x2;
+        double y12 = y1 - y2;
+        double x23 = x2 - x3;
+        double y23 = y2 - y3;
+        double x34 = x3 - x4;
+        double y34 = y3 - y4;
+
+        double l12 = Math.sqrt(x12 * x12 + y12 * y12);
+        double l23 = Math.sqrt(x23 * x23 + y23 * y23);
+        double l34 = Math.sqrt(x34 * x34 + y34 * y34);
+
+        // All edges are zero
+        if (l12 == 0.0 && l23 == 0.0 && l34 == 0.0) {
+            // NOTHING
+            return;
+        }
+
+        // One zero edge
+        if (l12 == 0.0 && l23 == 0.0) {
+            addDashLine(x3, y3, x4, y4);
+            return;
+        }
+
+        if (l23 == 0.0 && l34 == 0.0) {
+            addDashLine(x1, y1, x2, y2);
+            return;
+        }
+
+        if (l12 == 0.0 && l34 == 0.0) {
+            addDashLine(x2, y2, x3, y3);
+            return;
+        }
+
+        double ax = x4 - x1 + 3.0 * (x2 - x3);
+        double ay = y4 - y1 + 3.0 * (y2 - y3);
+        double bx = 3.0 * (x1 + x3 - x2 - x2);
+        double by = 3.0 * (y1 + y3 - y2 - y2);
+        double cx = 3.0 * (x2 - x1);
+        double cy = 3.0 * (y2 - y1);
+        double dx = x1;
+        double dy = y1;
+
+        double px1 = 0.0;
+        double py1 = 0.0;
+        double prev = 0.0;
+
+        dasher.init(new DashIterator.Cubic(x1, y1, x2, y2, x3, y3, x4, y4));
+
+        while(!dasher.eof()) {
+
+            double t = dasher.getValue();
+            scx = t * (t * (t * ax + bx) + cx) + dx;
+            scy = t * (t * (t * ay + by) + cy) + dy;
+            if (dasher.isOpen()) {
+                px1 = scx;
+                py1 = scy;
+                double dx1 = t * (t * (ax + ax + ax) + bx + bx) + cx;
+                double dy1 = t * (t * (ay + ay + ay) + by + by) + cy;
+                double w = w2 / Math.sqrt(dx1 * dx1 + dy1 * dy1);
+                double mx1 = - dy1 * w;
+                double my1 =   dx1 * w;
+                double lx1 = px1 + mx1;
+                double ly1 = py1 + my1;
+                double rx1 = px1 - mx1;
+                double ry1 = py1 - my1;
+                if (isMove) {
+                    isMove = false;
+                    smx = px1;
+                    smy = py1;
+                    rp.clean();
+                    lp.moveTo(lx1, ly1);
+                    rp.moveTo(rx1, ry1);
+                } else {
+                    addJoin(lp, x1, y1, lx1, ly1, true);
+                    addJoin(rp, x1, y1, rx1, ry1, false);
+                }
+            } else 
+                if (dasher.isContinue()) {
+                    double sx1 = x2 - x23 * prev;
+                    double sy1 = y2 - y23 * prev;
+                    double sx2 = x3 - x34 * prev;
+                    double sy2 = y3 - y34 * prev;
+                    double sx3 = sx1 + (sx2 - sx1) * prev;
+                    double sy3 = sy1 + (sy2 - sy1) * prev;
+                    double t2 = (t - prev) / (1 - prev);
+                    double sx4 = sx3 + (sx2 - sx3) * t2;
+                    double sy4 = sy3 + (sy2 - sy3) * t2;
+
+                    double px4 = scx;
+                    double py4 = scy;
+                    double px2 = px1 + (sx3 - px1) * t2;
+                    double py2 = py1 + (sy3 - py1) * t2;
+                    double px3 = px2 + (sx4 - px2) * t2;
+                    double py3 = py2 + (sy4 - py2) * t2;
+
+                    addCubic(px1, py1, px2, py2, px3, py3, px4, py4);
+                    if (dasher.isClosed()) {
+                        addCap(lp, px4, py4, rp.xLast, rp.yLast);
+                        lp.combine(rp);
+                        if (isFirst) {
+                            isFirst = false;
+                            fmx = smx;
+                            fmy = smy;
+                            sp = lp;
+                            lp = new BufferedPath();
+                        } else {
+                            addCap(lp, smx, smy, lp.xMove, lp.yMove);
+                            lp.closePath();
+                        }
+                        isMove = true;
+                    }
+                }
+
+            prev = t;
+            dasher.next();
+        }
+    }
+
+    /**
+     * Dasher class provides dashing for particular dash style.
+     */
+    class Dasher {
+        
+        /** The pos. */
+        double pos;
+        
+        /** The first. */
+        boolean close, visible, first;
+        
+        /** The dash. */
+        float dash[];
+        
+        /** The phase. */
+        float phase;
+        
+        /** The index. */
+        int index;
+        
+        /** The iter. */
+        DashIterator iter;
+        
+        /**
+         * Instantiates a new dasher.
+         * 
+         * @param dash the dash
+         * @param phase the phase
+         */
+        Dasher(float dash[], float phase) {
+            this.dash = dash;
+            this.phase = phase;
+            index = 0;
+            pos = phase;
+            visible = true;
+            while (pos >= dash[index]) {
+                visible = !visible;
+                pos -= dash[index];
+                index = (index + 1) % dash.length;
+            }            
+            pos = -pos;
+            first = visible;
+        }
+        
+        /**
+         * Inits the.
+         * 
+         * @param iter the iter
+         */
+        void init(DashIterator iter) {
+            this.iter = iter;
+            close = true;
+        }
+        
+        /**
+         * Checks if is open.
+         * 
+         * @return true, if is open
+         */
+        boolean isOpen() {
+            return visible && pos < iter.length;
+        }
+        
+        /**
+         * Checks if is continue.
+         * 
+         * @return true, if is continue
+         */
+        boolean isContinue() {
+            return !visible && pos > 0;
+        }
+        
+        /**
+         * Checks if is closed.
+         * 
+         * @return true, if is closed
+         */
+        boolean isClosed() {
+            return close;
+        }
+        
+        /**
+         * Checks if is connected.
+         * 
+         * @return true, if is connected
+         */
+        boolean isConnected() {
+            return first && !close;
+        }
+
+        /**
+         * Eof.
+         * 
+         * @return true, if successful
+         */
+        boolean eof() {
+            if (!close) {
+                pos -= iter.length;
+                return true;
+            }
+            if (pos >= iter.length) {
+                if (visible) {
+                    pos -= iter.length;
+                    return true;
+                }
+                close = pos == iter.length;
+            }
+            return false;
+        }
+        
+        /**
+         * Next.
+         */
+        void next() {
+            if (close) {
+                pos += dash[index];
+                index = (index + 1) % dash.length;
+            } else {
+                // Go back
+                index = (index + dash.length - 1) % dash.length;
+                pos -= dash[index];
+            }
+            visible = !visible;
+        }
+        
+        /**
+         * Gets the value.
+         * 
+         * @return the value
+         */
+        double getValue() {
+            double t = iter.getNext(pos);
+            return t < 0 ? 0 : (t > 1 ? 1 : t);
+        }
+        
+    }
+
+    /**
+     * DashIterator class provides dashing for particular segment type.
+     */
+    static abstract class DashIterator {
+
+        /** The Constant FLATNESS. */
+        static final double FLATNESS = 1.0;
+
+        /**
+         * The Class Line.
+         */
+        static class Line extends DashIterator {
+
+            /**
+             * Instantiates a new line.
+             * 
+             * @param len the len
+             */
+            Line(double len) {
+                length = len;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                return dashPos / length;
+            }
+
+        }
+
+        /**
+         * The Class Quad.
+         */
+        static class Quad extends DashIterator {
+
+            /** The val size. */
+            int valSize;
+            
+            /** The val pos. */
+            int valPos;
+            
+            /** The cur len. */
+            double curLen;
+            
+            /** The prev len. */
+            double prevLen;
+            
+            /** The last len. */
+            double lastLen;
+            
+            /** The values. */
+            double[] values;
+            
+            /** The step. */
+            double step;
+
+            /**
+             * Instantiates a new quad.
+             * 
+             * @param x1 the x1
+             * @param y1 the y1
+             * @param x2 the x2
+             * @param y2 the y2
+             * @param x3 the x3
+             * @param y3 the y3
+             */
+            Quad(double x1, double y1, double x2, double y2, double x3, double y3) {
+
+                double nx = x1 + x3 - x2 - x2;
+                double ny = y1 + y3 - y2 - y2;
+
+                int n = (int)(1 + Math.sqrt(0.75 * (Math.abs(nx) + Math.abs(ny)) * FLATNESS));
+                step = 1.0 / n;
+
+                double ax = x1 + x3 - x2 - x2;
+                double ay = y1 + y3 - y2 - y2;
+                double bx = 2.0 * (x2 - x1);
+                double by = 2.0 * (y2 - y1);
+
+                double dx1 = step * (step * ax + bx);
+                double dy1 = step * (step * ay + by);
+                double dx2 = step * (step * ax * 2.0);
+                double dy2 = step * (step * ay * 2.0);
+                double vx = x1;
+                double vy = y1;
+
+                valSize = n;
+                values = new double[valSize];
+                double pvx = vx;
+                double pvy = vy;
+                length = 0.0;
+                for(int i = 0; i < n; i++) {
+                    vx += dx1;
+                    vy += dy1;
+                    dx1 += dx2;
+                    dy1 += dy2;
+                    double lx = vx - pvx;
+                    double ly = vy - pvy;
+                    values[i] = Math.sqrt(lx * lx + ly * ly);
+                    length += values[i];
+                    pvx = vx;
+                    pvy = vy;
+                }
+
+                valPos = 0;
+                curLen = 0.0;
+                prevLen = 0.0;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                double t = 2.0;
+                while (curLen <= dashPos && valPos < valSize) {
+                    prevLen = curLen;
+                    curLen += lastLen = values[valPos++];
+                }
+                if (curLen > dashPos) {
+                    t = (valPos - 1 + (dashPos - prevLen) / lastLen) * step;
+                }
+                return t;
+            }
+
+        }
+
+        /**
+         * The Class Cubic.
+         */
+        static class Cubic extends DashIterator {
+
+            /** The val size. */
+            int valSize;
+            
+            /** The val pos. */
+            int valPos;
+            
+            /** The cur len. */
+            double curLen;
+            
+            /** The prev len. */
+            double prevLen;
+            
+            /** The last len. */
+            double lastLen;
+            
+            /** The values. */
+            double[] values;
+            
+            /** The step. */
+            double step;
+
+            /**
+             * Instantiates a new cubic.
+             * 
+             * @param x1 the x1
+             * @param y1 the y1
+             * @param x2 the x2
+             * @param y2 the y2
+             * @param x3 the x3
+             * @param y3 the y3
+             * @param x4 the x4
+             * @param y4 the y4
+             */
+            Cubic(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) {
+
+                double nx1 = x1 + x3 - x2 - x2;
+                double ny1 = y1 + y3 - y2 - y2;
+                double nx2 = x2 + x4 - x3 - x3;
+                double ny2 = y2 + y4 - y3 - y3;
+
+                double max = Math.max(Math.abs(nx1) + Math.abs(ny1), Math.abs(nx2) + Math.abs(ny2));
+                int n = (int)(1 + Math.sqrt(0.75 * max) * FLATNESS);
+                step = 1.0 / n;
+
+                double ax = x4 - x1 + 3.0 * (x2 - x3);
+                double ay = y4 - y1 + 3.0 * (y2 - y3);
+                double bx = 3.0 * (x1 + x3 - x2 - x2);
+                double by = 3.0 * (y1 + y3 - y2 - y2);
+                double cx = 3.0 * (x2 - x1);
+                double cy = 3.0 * (y2 - y1);
+
+                double dx1 = step * (step * (step * ax + bx) + cx);
+                double dy1 = step * (step * (step * ay + by) + cy);
+                double dx2 = step * (step * (step * ax * 6.0 + bx * 2.0));
+                double dy2 = step * (step * (step * ay * 6.0 + by * 2.0));
+                double dx3 = step * (step * (step * ax * 6.0));
+                double dy3 = step * (step * (step * ay * 6.0));
+                double vx = x1;
+                double vy = y1;
+
+                valSize = n;
+                values = new double[valSize];
+                double pvx = vx;
+                double pvy = vy;
+                length = 0.0;
+                for(int i = 0; i < n; i++) {
+                    vx += dx1;
+                    vy += dy1;
+                    dx1 += dx2;
+                    dy1 += dy2;
+                    dx2 += dx3;
+                    dy2 += dy3;
+                    double lx = vx - pvx;
+                    double ly = vy - pvy;
+                    values[i] = Math.sqrt(lx * lx + ly * ly);
+                    length += values[i];
+                    pvx = vx;
+                    pvy = vy;
+                }
+
+                valPos = 0;
+                curLen = 0.0;
+                prevLen = 0.0;
+            }
+
+            @Override
+            double getNext(double dashPos) {
+                double t = 2.0;
+                while (curLen <= dashPos && valPos < valSize) {
+                    prevLen = curLen;
+                    curLen += lastLen = values[valPos++];
+                }
+                if (curLen > dashPos) {
+                    t = (valPos - 1 + (dashPos - prevLen) / lastLen) * step;
+                }
+                return t;
+            }
+
+        }
+
+        /** The length. */
+        double length;
+
+        /**
+         * Gets the next.
+         * 
+         * @param dashPos the dash pos
+         * 
+         * @return the next
+         */
+        abstract double getNext(double dashPos);
+
+    }
+
+    /**
+     * BufferedPath class provides work path storing and processing.
+     */
+    static class BufferedPath {
+
+        /** The Constant bufCapacity. */
+        private static final int bufCapacity = 10;
+
+        /** The point shift. */
+        static int pointShift[] = {
+                2,  // MOVETO
+                2,  // LINETO
+                4,  // QUADTO
+                6,  // CUBICTO
+                0}; // CLOSE
+
+        /** The types. */
+        byte[] types;
+        
+        /** The points. */
+        float[] points;
+        
+        /** The type size. */
+        int typeSize;
+        
+        /** The point size. */
+        int pointSize;
+
+        /** The x last. */
+        float xLast;
+        
+        /** The y last. */
+        float yLast;
+        
+        /** The x move. */
+        float xMove;
+        
+        /** The y move. */
+        float yMove;
+
+        /**
+         * Instantiates a new buffered path.
+         */
+        public BufferedPath() {
+            types = new byte[bufCapacity];
+            points = new float[bufCapacity * 2];
+        }
+
+        /**
+         * Check buf.
+         * 
+         * @param typeCount the type count
+         * @param pointCount the point count
+         */
+        void checkBuf(int typeCount, int pointCount) {
+            if (typeSize + typeCount > types.length) {
+                byte tmp[] = new byte[typeSize + Math.max(bufCapacity, typeCount)];
+                System.arraycopy(types, 0, tmp, 0, typeSize);
+                types = tmp;
+            }
+            if (pointSize + pointCount > points.length) {
+                float tmp[] = new float[pointSize + Math.max(bufCapacity * 2, pointCount)];
+                System.arraycopy(points, 0, tmp, 0, pointSize);
+                points = tmp;
+            }
+        }
+
+        /**
+         * Checks if is empty.
+         * 
+         * @return true, if is empty
+         */
+        boolean isEmpty() {
+            return typeSize == 0;
+        }
+
+        /**
+         * Clean.
+         */
+        void clean() {
+            typeSize = 0;
+            pointSize = 0;
+        }
+
+        /**
+         * Move to.
+         * 
+         * @param x the x
+         * @param y the y
+         */
+        void moveTo(double x, double y) {
+            checkBuf(1, 2);
+            types[typeSize++] = PathIterator.SEG_MOVETO;
+            points[pointSize++] = xMove = (float)x;
+            points[pointSize++] = yMove = (float)y;
+        }
+
+        /**
+         * Line to.
+         * 
+         * @param x the x
+         * @param y the y
+         */
+        void lineTo(double x, double y) {
+            checkBuf(1, 2);
+            types[typeSize++] = PathIterator.SEG_LINETO;
+            points[pointSize++] = xLast = (float)x;
+            points[pointSize++] = yLast = (float)y;
+        }
+
+        /**
+         * Quad to.
+         * 
+         * @param x1 the x1
+         * @param y1 the y1
+         * @param x2 the x2
+         * @param y2 the y2
+         */
+        void quadTo(double x1, double y1, double x2, double y2) {
+            checkBuf(1, 4);
+            types[typeSize++] = PathIterator.SEG_QUADTO;
+            points[pointSize++] = (float)x1;
+            points[pointSize++] = (float)y1;
+            points[pointSize++] = xLast = (float)x2;
+            points[pointSize++] = yLast = (float)y2;
+        }
+
+        /**
+         * Cubic to.
+         * 
+         * @param x1 the x1
+         * @param y1 the y1
+         * @param x2 the x2
+         * @param y2 the y2
+         * @param x3 the x3
+         * @param y3 the y3
+         */
+        void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3) {
+            checkBuf(1, 6);
+            types[typeSize++] = PathIterator.SEG_CUBICTO;
+            points[pointSize++] = (float)x1;
+            points[pointSize++] = (float)y1;
+            points[pointSize++] = (float)x2;
+            points[pointSize++] = (float)y2;
+            points[pointSize++] = xLast = (float)x3;
+            points[pointSize++] = yLast = (float)y3;
+        }
+
+        /**
+         * Close path.
+         */
+        void closePath() {
+            checkBuf(1, 0);
+            types[typeSize++] = PathIterator.SEG_CLOSE;
+        }
+
+        /**
+         * Sets the last.
+         * 
+         * @param x the x
+         * @param y the y
+         */
+        void setLast(double x, double y) {
+            points[pointSize - 2] = xLast = (float)x;
+            points[pointSize - 1] = yLast = (float)y;
+        }
+
+        /**
+         * Append.
+         * 
+         * @param p the p
+         */
+        void append(BufferedPath p) {
+            checkBuf(p.typeSize, p.pointSize);
+            System.arraycopy(p.points, 0, points, pointSize, p.pointSize);
+            System.arraycopy(p.types, 0, types, typeSize, p.typeSize);
+            pointSize += p.pointSize;
+            typeSize += p.typeSize;
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Append reverse.
+         * 
+         * @param p the p
+         */
+        void appendReverse(BufferedPath p) {
+            checkBuf(p.typeSize, p.pointSize);
+            // Skip last point, beacause it's the first point of the second path
+            for(int i = p.pointSize - 2; i >= 0; i -= 2) {
+                points[pointSize++] = p.points[i + 0];
+                points[pointSize++] = p.points[i + 1];
+            }
+            // Skip first type, beacuse it's always MOVETO
+            int closeIndex = 0;
+            for(int i = p.typeSize - 1; i >= 0; i--) {
+                byte type = p.types[i];
+                if (type == PathIterator.SEG_MOVETO) {
+                    types[closeIndex] = PathIterator.SEG_MOVETO;
+                    types[typeSize++] = PathIterator.SEG_CLOSE;
+                } else {
+                    if (type == PathIterator.SEG_CLOSE) {
+                        closeIndex = typeSize;
+                    }
+                    types[typeSize++] = type;
+                }
+            }
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Join.
+         * 
+         * @param p the p
+         */
+        void join(BufferedPath p) {
+            // Skip MOVETO
+            checkBuf(p.typeSize - 1, p.pointSize - 2);
+            System.arraycopy(p.points, 2, points, pointSize, p.pointSize - 2);
+            System.arraycopy(p.types, 1, types, typeSize, p.typeSize - 1);
+            pointSize += p.pointSize - 2;
+            typeSize += p.typeSize - 1;
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Combine.
+         * 
+         * @param p the p
+         */
+        void combine(BufferedPath p) {
+            checkBuf(p.typeSize - 1, p.pointSize - 2);
+            // Skip last point, beacause it's the first point of the second path
+            for(int i = p.pointSize - 4; i >= 0; i -= 2) {
+                points[pointSize++] = p.points[i + 0];
+                points[pointSize++] = p.points[i + 1];
+            }
+            // Skip first type, beacuse it's always MOVETO
+            for(int i = p.typeSize - 1; i >= 1; i--) {
+                types[typeSize++] = p.types[i];
+            }
+            xLast = points[pointSize - 2];
+            yLast = points[pointSize - 1];
+        }
+
+        /**
+         * Creates the general path.
+         * 
+         * @return the general path
+         */
+        GeneralPath createGeneralPath() {
+            GeneralPath p = new GeneralPath();
+            int j = 0;
+            for(int i = 0; i < typeSize; i++) {
+                int type = types[i];
+                switch(type){
+                case PathIterator.SEG_MOVETO:
+                    p.moveTo(points[j], points[j + 1]);
+                    break;
+                case PathIterator.SEG_LINETO:
+                    p.lineTo(points[j], points[j + 1]);
+                    break;
+                case PathIterator.SEG_QUADTO:
+                    p.quadTo(points[j], points[j + 1], points[j + 2], points[j + 3]);
+                    break;
+                case PathIterator.SEG_CUBICTO:
+                    p.curveTo(points[j], points[j + 1], points[j + 2], points[j + 3], points[j + 4], points[j + 5]);
+                    break;
+                case PathIterator.SEG_CLOSE:
+                    p.closePath();
+                    break;
+                }
+                j += pointShift[type];
+            }
+            return p;
+        }
+
+    }
+
+}
+
diff --git a/awt/java/awt/BufferCapabilities.java b/awt/java/awt/BufferCapabilities.java
new file mode 100644
index 0000000..80e8add
--- /dev/null
+++ b/awt/java/awt/BufferCapabilities.java
@@ -0,0 +1,185 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+
+/**
+ * The BufferCapabilities class represents the capabilities 
+ * and other properties of the image buffers.
+ */
+public class BufferCapabilities implements Cloneable {
+    
+    /** The front buffer capabilities. */
+    private final ImageCapabilities frontBufferCapabilities;
+    
+    /** The back buffer capabilities. */
+    private final ImageCapabilities backBufferCapabilities;
+    
+    /** The flip contents. */
+    private final FlipContents flipContents;
+
+    /**
+     * Instantiates a new BufferCapabilities object.
+     * 
+     * @param frontBufferCapabilities the front buffer capabilities, 
+     * can not be null.
+     * @param backBufferCapabilities the the back and intermediate 
+     * buffers capabilities, can not be null.
+     * @param flipContents the back buffer contents after page flipping, 
+     * null if page flipping is not used.
+     */
+    public BufferCapabilities(ImageCapabilities frontBufferCapabilities, 
+            ImageCapabilities backBufferCapabilities, FlipContents flipContents) {
+        if (frontBufferCapabilities == null || backBufferCapabilities == null) {
+            throw new IllegalArgumentException();
+        }
+
+        this.frontBufferCapabilities = frontBufferCapabilities;
+        this.backBufferCapabilities = backBufferCapabilities;
+        this.flipContents = flipContents;
+    }
+
+    /**
+     * Returns a copy of the BufferCapabilities object.
+     * 
+     * @return a copy of the BufferCapabilities object.
+     */
+    @Override
+    public Object clone() {
+        return new BufferCapabilities(frontBufferCapabilities, backBufferCapabilities, flipContents);
+    }
+
+    /**
+     * Gets the image capabilities of the front buffer.
+     * 
+     * @return the ImageCapabilities object represented capabilities 
+     * of the front buffer. 
+     */
+    public ImageCapabilities getFrontBufferCapabilities() {
+        return frontBufferCapabilities;
+    }
+
+    /**
+     * Gets the image capabilities of the back buffer.
+     * 
+     * @return the ImageCapabilities object represented capabilities 
+     * of the back buffer. 
+     */
+    public ImageCapabilities getBackBufferCapabilities() {
+        return backBufferCapabilities;
+    }
+
+    /**
+     * Gets the flip contents of the back buffer after page-flipping. 
+     * 
+     * @return the FlipContents of the back buffer after page-flipping.
+     */
+    public FlipContents getFlipContents() {
+        return flipContents;
+    }
+
+    /**
+     * Checks if the buffer strategy uses page flipping.
+     * 
+     * @return true, if the buffer strategy uses page flipping,
+     * false otherwise.
+     */
+    public boolean isPageFlipping() {
+        return flipContents != null;
+    }
+
+    /**
+     * Checks if page flipping is only available in full-screen mode.
+     * 
+     * @return true, if page flipping is only available in full-screen mode,
+     * false otherwise.
+     */
+    public boolean isFullScreenRequired() {
+        return false;
+    }
+
+    /**
+     * Checks if page flipping can be performed using more than two buffers.
+     * 
+     * @return true, if page flipping can be performed using more than two buffers,
+     * false otherwise.
+     */
+    public boolean isMultiBufferAvailable() {
+        return false;
+    }
+
+    /**
+     * The FlipContents class represents a set of possible back buffer contents 
+     * after page-flipping.
+     */
+    public static final class FlipContents {
+        
+        /**
+         * The back buffered contents are cleared with the background color 
+         * after flipping.
+         */
+        public static final FlipContents BACKGROUND = new FlipContents();
+        
+        /** 
+         * The back buffered contents are copied to the front buffer before 
+         * flipping.
+         */
+        public static final FlipContents COPIED = new FlipContents();
+        
+        /** 
+         * The back buffer contents are the prior contents of the 
+         * front buffer.
+         */
+        public static final FlipContents PRIOR = new FlipContents();
+        
+        /** 
+         * The back buffer contents are undefined after flipping 
+         */
+        public static final FlipContents UNDEFINED = new FlipContents();
+
+        /**
+         * Instantiates a new flip contents.
+         */
+        private FlipContents() {
+
+        }
+
+        /**
+         * Returns the hash code of the FlipContents object.
+         * 
+         * @return the hash code of the FlipContents object.
+         */
+        @Override
+        public int hashCode() {
+            return super.hashCode();
+        }
+
+        /**
+         * Returns the String representation of the FlipContents object.
+         * 
+         * @return the string
+         */
+        @Override
+        public String toString() {
+            return super.toString();
+        }
+    }
+}
diff --git a/awt/java/awt/Color.java b/awt/java/awt/Color.java
new file mode 100644
index 0000000..e1e4178
--- /dev/null
+++ b/awt/java/awt/Color.java
@@ -0,0 +1,881 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Color class defines colors in the default sRGB color 
+ * space or in the specified ColorSpace. Every Color contains alpha value.
+ * The alpha value defines the transparency of a color and can be represented
+ * by a float value in the range 0.0 - 1.0 or 0 - 255. 
+  */
+public class Color implements Paint, Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 118526816881161077L;
+
+    /*
+     * The values of the following colors are based on 1.5 release behavior which
+     * can be revealed using the following or similar code:
+     *   Color c = Color.white;
+     *   System.out.println(c);
+     */
+
+    /** The color white. */
+    public static final Color white = new Color(255, 255, 255);
+
+    /** The color white. */
+    public static final Color WHITE = white;
+
+    /** The color light gray. */
+    public static final Color lightGray = new Color(192, 192, 192);
+
+    /** The color light gray. */
+    public static final Color LIGHT_GRAY = lightGray;
+
+    /** The color gray. */
+    public static final Color gray = new Color(128, 128, 128);
+
+    /** The color gray. */
+    public static final Color GRAY = gray;
+
+    /** The color dark gray. */
+    public static final Color darkGray = new Color(64, 64, 64);
+
+    /** The color dark gray. */
+    public static final Color DARK_GRAY = darkGray;
+
+    /** The color black. */
+    public static final Color black = new Color(0, 0, 0);
+
+    /** The color black. */
+    public static final Color BLACK = black;
+
+    /** The color red. */
+    public static final Color red = new Color(255, 0, 0);
+
+    /** The color red. */
+    public static final Color RED = red;
+
+    /** The color pink. */
+    public static final Color pink = new Color(255, 175, 175);
+
+    /** The color pink. */
+    public static final Color PINK = pink;
+
+    /** The color orange. */
+    public static final Color orange = new Color(255, 200, 0);
+
+    /** The color orange. */
+    public static final Color ORANGE = orange;
+
+    /** The color yellow. */
+    public static final Color yellow = new Color(255, 255, 0);
+
+    /** The color yellow. */
+    public static final Color YELLOW = yellow;
+
+    /** The color green. */
+    public static final Color green = new Color(0, 255, 0);
+
+    /** The color green. */
+    public static final Color GREEN = green;
+
+    /** The color magenta. */
+    public static final Color magenta = new Color(255, 0, 255);
+
+    /** The color magenta. */
+    public static final Color MAGENTA = magenta;
+
+    /** The color cyan. */
+    public static final Color cyan = new Color(0, 255, 255);
+
+    /** The color cyan. */
+    public static final Color CYAN = cyan;
+
+    /** The color blue. */
+    public static final Color blue = new Color(0, 0, 255);
+
+    /** The color blue. */
+    public static final Color BLUE = blue;
+
+    /** integer RGB value. */
+    int value;
+
+    /** Float sRGB value. */
+    private float[] frgbvalue;
+
+    /** Color in an arbitrary color space with <code>float</code> components. If null, other value should be used. */
+    private float fvalue[];
+
+    /** Float alpha value. If frgbvalue is null, this is not valid data. */
+    private float falpha;
+
+    /** The color's color space if applicable. */
+    private ColorSpace cs;
+
+    /*
+     * The value of the SCALE_FACTOR is based on 1.5 release behavior which
+     * can be revealed using the following code:
+     *   Color c = new Color(100, 100, 100);
+     *   Color bc = c.brighter();
+     *   System.out.println("Brighter factor: " + ((float)c.getRed())/((float)bc.getRed()));
+     *   Color dc = c.darker();
+     *   System.out.println("Darker factor: " + ((float)dc.getRed())/((float)c.getRed()));
+     * The result is the same for brighter and darker methods, so we need only
+     * one scale factor for both.
+     */
+    /** The Constant SCALE_FACTOR. */
+    private static final double SCALE_FACTOR = 0.7;
+
+    /** The Constant MIN_SCALABLE. */
+    private static final int MIN_SCALABLE = 3; // should increase when multiplied by SCALE_FACTOR
+
+    /** The current paint context. */
+    transient private PaintContext currentPaintContext;
+
+    /**
+     * Creates a color in the specified ColorSpace, the specified color 
+     * components and the specified alpha. 
+     * 
+     * @param cspace the ColorSpace to be used to define the components.
+     * @param components the components.
+     * @param alpha the alpha.
+     */
+    public Color(ColorSpace cspace, float[] components, float alpha) {
+        int nComps = cspace.getNumComponents();
+        float comp;
+        fvalue = new float[nComps];
+
+        for(int i=0 ; i<nComps; i++) {
+            comp = components[i];
+            if(comp < 0.0f || comp > 1.0f) {
+                // awt.107=Color parameter outside of expected range: component {0}.
+                throw new IllegalArgumentException(
+                        Messages.getString("awt.107", i)); //$NON-NLS-1$
+            }
+            fvalue[i] = components[i];
+        }
+
+        if (alpha < 0.0f || alpha > 1.0f) {
+            // awt.108=Alpha value outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.108")); //$NON-NLS-1$
+        }
+        falpha = alpha;
+
+        cs = cspace;
+
+        frgbvalue = cs.toRGB(fvalue);
+
+        value =  ((int)(frgbvalue[2]*255 + 0.5))    |
+                (((int)(frgbvalue[1]*255 + 0.5)) << 8 )  |
+                (((int)(frgbvalue[0]*255 + 0.5)) << 16 ) |
+                (((int)(falpha*255 + 0.5)) << 24 );
+    }
+
+    /**
+     * Instantiates a new sRGB color with the specified combined 
+     * RGBA value consisting of the alpha component in bits 24-31, 
+     * the red component in bits 16-23, the green component in bits 8-15, 
+     * and the blue component in bits 0-7. If the hasalpha argument is 
+     * false, the alpha has default value - 255.
+     * 
+     * @param rgba the RGBA components.
+     * @param hasAlpha alpha parameter is true if alpha bits are valid,
+     * false otherwise.
+     */
+    public Color(int rgba, boolean hasAlpha) {
+        if (!hasAlpha) {
+            value = rgba | 0xFF000000;
+        } else {
+            value = rgba;
+        }
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, blue and alpha 
+     * components.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     * @param a the alpha component.
+     */
+    public Color(int r, int g, int b, int a) {
+        if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b || (a & 0xFF) != a) {
+            // awt.109=Color parameter outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
+        }
+        value = b | (g << 8) | (r << 16) | (a << 24);
+    }
+
+    /**
+     * Instantiates a new opaque sRGB color with the specified red, green, 
+     * and blue values. The Alpha component is set to the default - 1.0.
+     * 
+     * @param r the red component. 
+     * @param g the green component.
+     * @param b the blue component.
+     */
+    public Color(int r, int g, int b) {
+        if ((r & 0xFF) != r || (g & 0xFF) != g || (b & 0xFF) != b) {
+            // awt.109=Color parameter outside of expected range.
+            throw new IllegalArgumentException(Messages.getString("awt.109")); //$NON-NLS-1$
+        }
+        // 0xFF for alpha channel
+        value = b | (g << 8) | (r << 16) | 0xFF000000;
+    }
+
+    /**
+     * Instantiates a new sRGB color with the specified 
+     * RGB value consisting of the red component in bits 16-23, 
+     * the green component in bits 8-15, and the blue component 
+     * in bits 0-7. Alpha has default value - 255.
+     * 
+     * @param rgb the RGB components.
+     */
+    public Color(int rgb) {
+        value = rgb | 0xFF000000;
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, blue and alpha 
+     * components.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     * @param a the alpha component.
+     */
+    public Color(float r, float g, float b, float a) {
+        this((int)(r*255+0.5),
+                (int)(g*255+0.5),
+                (int)(b*255+0.5),
+                (int)(a*255+0.5));
+        falpha = a;
+        fvalue = new float[3];
+        fvalue[0] = r;
+        fvalue[1] = g;
+        fvalue[2] = b;
+        frgbvalue = fvalue;
+    }
+
+    /**
+     * Instantiates a new color with the specified red, green, and blue 
+     * components and default alfa value - 1.0.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     */
+    public Color(float r, float g, float b) {
+        this(r, g, b, 1.0f);
+    }
+
+    public PaintContext createContext(
+            ColorModel cm,
+            Rectangle r,
+            Rectangle2D r2d,
+            AffineTransform xform,
+            RenderingHints rhs
+    ) {
+        if(currentPaintContext != null) {
+            return currentPaintContext;
+        }
+        currentPaintContext = new Color.ColorPaintContext(value);
+        return currentPaintContext;
+    }
+
+    /**
+     * Returns a string representation of the Color object.
+     * 
+     * @return the string representation of the Color object.
+     */
+    @Override
+    public String toString() {
+        /*
+           The format of the string is based on 1.5 release behavior which
+           can be revealed using the following code:
+
+           Color c = new Color(1, 2, 3);
+           System.out.println(c);
+        */
+        
+        return getClass().getName() +
+                "[r=" + getRed() + //$NON-NLS-1$
+                ",g=" + getGreen() + //$NON-NLS-1$
+                ",b=" + getBlue() + //$NON-NLS-1$
+                "]"; //$NON-NLS-1$
+    }
+
+    /**
+     * Compares the specified Object to the Color.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is a Color whose 
+     * value is equal to this Color, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if(obj instanceof Color) {
+            return ((Color)obj).value == this.value;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a float array containing the color and alpha components of 
+     * the Color in the specified ColorSpace. 
+     * 
+     * @param colorSpace the specified ColorSpace.
+     * @param components the results of this method will be written to
+     * this float array. If null, a float array will be created.
+     * 
+     * @return the color and alpha components in a float array.
+     */
+    public float[] getComponents(ColorSpace colorSpace, float[] components) {
+        int nComps = colorSpace.getNumComponents();
+        if(components == null) {
+            components = new float[nComps+1];
+        }
+
+        getColorComponents(colorSpace, components);
+
+        if(frgbvalue != null) {
+            components[nComps] = falpha;
+        } else {
+            components[nComps] = getAlpha()/255f;
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a float array containing the color components of 
+     * the Color in the specified ColorSpace.
+     * 
+     * @param colorSpace the specified ColorSpace.
+     * @param components the results of this method will be written to
+     * this float array. If null, a float array will be created.
+     * 
+     * @return the color components in a float array.
+     */
+    public float[] getColorComponents(ColorSpace colorSpace, float[] components) {
+        float[] cieXYZComponents = getColorSpace().toCIEXYZ(getColorComponents(null));
+        float[] csComponents = colorSpace.fromCIEXYZ(cieXYZComponents);
+
+        if(components == null) {
+            return csComponents;
+        }
+
+        for(int i=0; i<csComponents.length; i++) {
+            components[i] = csComponents[i];
+        }
+
+        return components;
+    }
+
+    /**
+     * Gets the ColorSpace of this Color.
+     * 
+     * @return the ColorSpace object.
+     */
+    public ColorSpace getColorSpace() {
+        if (cs == null) {
+            cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        }
+
+        return cs;
+    }
+
+    /**
+     * Creates a new Color which is a darker than this Color
+     * according to a fixed scale factor.
+     * 
+     * @return the darker Color.
+     */
+    public Color darker() {
+        return new Color(
+                (int)(getRed()*SCALE_FACTOR),
+                (int)(getGreen()*SCALE_FACTOR),
+                (int)(getBlue()*SCALE_FACTOR));
+    }
+
+    /**
+     * Creates a new Color which is a brighter than this Color.
+     * 
+     * @return the brighter Color.
+     */
+    public Color brighter() {
+
+        int r = getRed();
+        int b = getBlue();
+        int g = getGreen();
+
+        if(r == 0 && b == 0 && g == 0) {
+            return new Color(MIN_SCALABLE, MIN_SCALABLE, MIN_SCALABLE);
+        }
+
+        if(r < MIN_SCALABLE && r != 0) {
+            r = MIN_SCALABLE;
+        } else {
+            r = (int) (r/SCALE_FACTOR);
+            r = (r > 255) ? 255 : r;
+        }
+
+        if(b < MIN_SCALABLE && b != 0) {
+            b = MIN_SCALABLE;
+        } else {
+            b = (int) (b/SCALE_FACTOR);
+            b = (b > 255) ? 255 : b;
+        }
+
+        if(g < MIN_SCALABLE && g != 0) {
+            g = MIN_SCALABLE;
+        } else {
+            g = (int) (g/SCALE_FACTOR);
+            g = (g > 255) ? 255 : g;
+        }
+
+        return new Color(r, g, b);
+    }
+
+    /**
+     * Returns a float array containing the color and alpha components of 
+     * the Color in the default sRGB color space. 
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the RGB color and alpha components in a float array.
+     */
+    public float[] getRGBComponents(float[] components) {
+        if(components == null) {
+            components = new float[4];
+        }
+
+        if(frgbvalue != null) {
+            components[3] = falpha;
+        } else {
+            components[3] = getAlpha()/255f;
+        }
+
+        getRGBColorComponents(components);
+
+        return components;
+    }
+
+    /**
+     * Returns a float array containing the color components of 
+     * the Color in the default sRGB color space. 
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the RGB color components in a float array.
+     */
+    public float[] getRGBColorComponents(float[] components) {
+        if(components == null) {
+            components = new float[3];
+        }
+
+        if(frgbvalue != null) {
+            components[2] = frgbvalue[2];
+            components[1] = frgbvalue[1];
+            components[0] = frgbvalue[0];
+        } else {
+            components[2] = getBlue()/255f;
+            components[1] = getGreen()/255f;
+            components[0] = getRed()/255f;
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a float array which contains the color and alpha components of 
+     * the Color in the ColorSpace of the Color.
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the color and alpha components in a float array.
+     */
+    public float[] getComponents(float[] components) {
+        if(fvalue == null) {
+            return getRGBComponents(components);
+        }
+
+        int nColorComps = fvalue.length;
+
+        if(components == null) {
+            components = new float[nColorComps+1];
+        }
+
+        getColorComponents(components);
+
+        components[nColorComps] = falpha;
+
+        return components;
+    }
+
+    /**
+     * Returns a float array which contains the color components of 
+     * the Color in the ColorSpace of the Color.
+     * 
+     * @param components the results of this method will be written to
+     * this float array. A new float array will be created if this
+     * argument is null.
+     * 
+     * @return the color components in a float array.
+     */
+    public float[] getColorComponents(float[] components) {
+        if(fvalue == null) {
+            return getRGBColorComponents(components);
+        }
+
+        if(components == null) {
+            components = new float[fvalue.length];
+        }
+
+        for(int i=0; i<fvalue.length; i++) {
+            components[i] = fvalue[i];
+        }
+
+        return components;
+    }
+
+    /**
+     * Returns a hash code of this Color object.
+     * 
+     * @return a hash code of this Color object.
+     */
+    @Override
+    public int hashCode() {
+        return value;
+    }
+
+    public int getTransparency() {
+        switch(getAlpha()) {
+            case 0xff:
+                return Transparency.OPAQUE;
+            case 0:
+                return Transparency.BITMASK;
+            default:
+                return Transparency.TRANSLUCENT;
+        }
+    }
+
+    /**
+     * Gets the red component of the Color in the range 0-255.
+     * 
+     * @return the red component of the Color.
+     */
+    public int getRed() {
+        return (value >> 16) & 0xFF;
+    }
+
+    /**
+     * Gets the RGB value that represents the color in the default sRGB ColorModel.
+     * 
+     * @return the RGB color value in the default sRGB ColorModel.
+     */
+    public int getRGB() {
+        return value;
+    }
+
+    /**
+     * Gets the green component of the Color in the range 0-255.
+     * 
+     * @return the green component of the Color.
+     */
+    public int getGreen() {
+        return (value >> 8) & 0xFF;
+    }
+
+    /**
+     * Gets the blue component of the Color in the range 0-255.
+     * 
+     * @return the blue component of the Color.
+     */
+    public int getBlue() {
+        return value & 0xFF;
+    }
+
+    /**
+     * Gets the alpha component of the Color in the range 0-255.
+     * 
+     * @return the alpha component of the Color.
+     */
+    public int getAlpha() {
+        return (value >> 24) & 0xFF;
+    }
+
+    /**
+     * Gets the Color from the specified string, or returns the Color
+     * specified by the second parameter.
+     * 
+     * @param nm the specified string.
+     * @param def the default Color.
+     * 
+     * @return the color from the specified string, or the Color
+     * specified by the second parameter.
+     */
+    public static Color getColor(String nm, Color def) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return def;
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets the Color from the specified string, or returns the Color converted
+     * from the second parameter.
+     * 
+     * @param nm the specified string.
+     * @param def the default Color.
+     * 
+     * @return the color from the specified string, or the Color
+     * converted from the second parameter.
+     */
+    public static Color getColor(String nm, int def) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return new Color(def);
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets the Color from the specified String.
+     * 
+     * @param nm the specified string.
+     * 
+     * @return the Color object, or null.
+     */
+    public static Color getColor(String nm) {
+        Integer integer = Integer.getInteger(nm);
+
+        if (integer == null) {
+            return null;
+        }
+
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Decodes a String to an integer and returns the specified opaque Color.
+     * 
+     * @param nm a String which represents an opaque color as a 24-bit integer.
+     * 
+     * @throws NumberFormatException if the specified string can not be
+     * converted to an integer.
+     */
+    public static Color decode(String nm) throws NumberFormatException {
+        Integer integer = Integer.decode(nm);
+        return new Color(integer.intValue());
+    }
+
+    /**
+     * Gets a Color object using the specified values of the HSB color model.
+     * 
+     * @param h the hue component of the Color.
+     * @param s the saturation of the Color.
+     * @param b the brightness of the Color.
+     * 
+     * @return a color object with the specified hue, saturation and 
+     * brightness values.
+     */
+    public static Color getHSBColor(float h, float s, float b) {
+        return new Color(HSBtoRGB(h, s, b));
+    }
+
+    /**
+     * Converts the Color specified by the RGB model to an equivalent 
+     * color in the HSB model.
+     * 
+     * @param r the red component.
+     * @param g the green component.
+     * @param b the blue component.
+     * @param hsbvals the array of result hue, saturation, brightness
+     * values or null.
+     * 
+     * @return the float array of hue, saturation, brightness values.
+     */
+    public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
+        if(hsbvals == null) {
+            hsbvals = new float[3];
+        }
+
+        int V = Math.max(b, Math.max(r, g));
+        int temp = Math.min(b, Math.min(r, g));
+
+        float H, S, B;
+
+        B = V/255.f;
+
+        if(V == temp) {
+            H = S = 0;
+        } else {
+            S = (V - temp)/((float)V);
+
+            float Cr = (V - r) / (float)(V - temp);
+            float Cg = (V - g) / (float)(V - temp);
+            float Cb = (V - b) / (float)(V - temp);
+
+            if (r == V) {
+                H = Cb - Cg;
+            } else if (g == V) {
+                H = 2 + Cr - Cb;
+            } else {
+                H = 4 + Cg - Cr;
+            }
+
+            H /= 6.f;
+            if(H < 0) {
+                H++;
+            }
+        }
+
+        hsbvals[0] = H;
+        hsbvals[1] = S;
+        hsbvals[2] = B;
+
+        return hsbvals;
+    }
+
+    /**
+     * Converts the Color specified by the HSB model to an equivalent 
+     * color in the default RGB model.
+     * 
+     * @param hue the hue component of the Color.
+     * @param saturation the saturation of the Color.
+     * @param brightness the brightness of the Color.
+     * 
+     * @return the RGB value of the color with the specified hue, 
+     * saturation and brightness.
+     */
+    public static int HSBtoRGB(float hue, float saturation, float brightness) {
+        float fr, fg, fb;
+
+        if(saturation == 0) {
+            fr = fg = fb = brightness;
+        } else {
+            float H = (hue - (float)Math.floor(hue)) * 6;
+            int I = (int) Math.floor(H);
+            float F = H - I;
+            float M = brightness * (1 - saturation);
+            float N = brightness * (1 - saturation * F);
+            float K = brightness * (1 - saturation * (1 - F));
+
+            switch(I) {
+                case 0:
+                    fr = brightness; fg = K; fb = M; break;
+                case 1:
+                    fr = N; fg = brightness; fb = M; break;
+                case 2:
+                    fr = M; fg = brightness; fb = K; break;
+                case 3:
+                    fr = M; fg = N; fb = brightness; break;
+                case 4:
+                    fr = K; fg = M; fb = brightness; break;
+                case 5:
+                    fr = brightness; fg = M; fb = N; break;
+                default:
+                    fr = fb = fg = 0; // impossible, to supress compiler error
+            }
+        }
+
+        int r = (int) (fr * 255. + 0.5);
+        int g = (int) (fg * 255. + 0.5);
+        int b = (int) (fb * 255. + 0.5);
+
+        return (r << 16) | (g << 8) | b | 0xFF000000;
+    }
+
+    /**
+     * The Class ColorPaintContext.
+     */
+    class ColorPaintContext implements PaintContext {
+        
+        /** The rgb value. */
+        int rgbValue;
+        
+        /** The saved raster. */
+        WritableRaster savedRaster = null;
+
+        /**
+         * Instantiates a new color paint context.
+         * 
+         * @param rgb the rgb
+         */
+        protected ColorPaintContext(int rgb) {
+            rgbValue = rgb;
+        }
+
+        public void dispose() {
+            savedRaster = null;
+        }
+
+        public ColorModel getColorModel() {
+            return ColorModel.getRGBdefault();
+        }
+
+        public Raster getRaster(int x, int y, int w, int h) {
+            if (savedRaster == null ||
+                    w != savedRaster.getWidth() ||
+                    h != savedRaster.getHeight()) {
+                savedRaster =
+                        getColorModel().createCompatibleWritableRaster(w, h);
+
+                // Suppose we have here simple INT/RGB color/sample model
+                DataBufferInt intBuffer =
+                        (DataBufferInt) savedRaster.getDataBuffer();
+                int rgbValues[] = intBuffer.getData();
+                int rgbFillValue = rgbValue;
+                Arrays.fill(rgbValues, rgbFillValue);
+            }
+
+            return savedRaster;
+        }
+    }
+}
+
diff --git a/awt/java/awt/Component.java b/awt/java/awt/Component.java
new file mode 100644
index 0000000..f19d285
--- /dev/null
+++ b/awt/java/awt/Component.java
@@ -0,0 +1,6408 @@
+/*
+ *  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 java.awt;
+
+//import java.awt.dnd.DropTarget;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.HierarchyBoundsListener;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.InputMethodListener;
+import java.awt.event.InvocationEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.event.PaintEvent;
+import java.awt.event.WindowEvent;
+import java.awt.im.InputContext;
+import java.awt.im.InputMethodRequests;
+import java.awt.image.BufferStrategy;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.awt.peer.ComponentPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+//???AWT
+//import javax.accessibility.Accessible;
+//import javax.accessibility.AccessibleComponent;
+//import javax.accessibility.AccessibleContext;
+//import javax.accessibility.AccessibleRole;
+//import javax.accessibility.AccessibleState;
+//import javax.accessibility.AccessibleStateSet;
+
+import org.apache.harmony.awt.ClipRegion;
+//import org.apache.harmony.awt.FieldsAccessor;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.state.State;
+//import org.apache.harmony.awt.text.TextFieldKit;
+//import org.apache.harmony.awt.text.TextKit;
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+/**
+ * The abstract Component class specifies an object with a graphical 
+ * representation that can be displayed on the screen and that can 
+ * interact with the user (for example: scrollbars, buttons, checkboxes).
+ */
+public abstract class Component implements ImageObserver, MenuContainer, Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -7644114512714619750L;
+
+    /** The Constant TOP_ALIGNMENT indicates the top alignment of the component. */
+    public static final float TOP_ALIGNMENT = 0.0f;
+
+    /** The Constant CENTER_ALIGNMENT indicates the center alignment of the component. */
+    public static final float CENTER_ALIGNMENT = 0.5f;
+
+    /** The Constant BOTTOM_ALIGNMENT indicates the bottom alignment of the component. */
+    public static final float BOTTOM_ALIGNMENT = 1.0f;
+
+    /** The Constant LEFT_ALIGNMENT indicates the left alignment of the component. */
+    public static final float LEFT_ALIGNMENT = 0.0f;
+
+    /** The Constant RIGHT_ALIGNMENT indicates the right alignment of the component. */
+    public static final float RIGHT_ALIGNMENT = 1.0f;
+
+    /** The Constant childClassesFlags. */
+    private static final Hashtable<Class<?>, Boolean> childClassesFlags = new Hashtable<Class<?>, Boolean>();
+
+    /** The Constant peer. */
+    private static final ComponentPeer peer = new ComponentPeer() {
+    };
+
+    /** The Constant incrementalImageUpdate. */
+    private static final boolean incrementalImageUpdate;
+
+    /** The toolkit. */
+    final transient Toolkit toolkit = Toolkit.getDefaultToolkit();
+
+    //???AWT
+    /*
+    protected abstract class AccessibleAWTComponent extends AccessibleContext implements
+            Serializable, AccessibleComponent {
+        private static final long serialVersionUID = 642321655757800191L;
+
+        protected class AccessibleAWTComponentHandler implements ComponentListener {
+            protected AccessibleAWTComponentHandler() {
+            }
+
+            public void componentHidden(ComponentEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                        AccessibleState.VISIBLE, null);
+            }
+
+            public void componentMoved(ComponentEvent e) {
+            }
+
+            public void componentResized(ComponentEvent e) {
+            }
+
+            public void componentShown(ComponentEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
+                        AccessibleState.VISIBLE);
+            }
+        }
+
+        protected class AccessibleAWTFocusHandler implements FocusListener {
+            public void focusGained(FocusEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null,
+                        AccessibleState.FOCUSED);
+            }
+
+            public void focusLost(FocusEvent e) {
+                if (behaviour.isLightweight()) {
+                    return;
+                }
+                firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
+                        AccessibleState.FOCUSED, null);
+            }
+        }
+    
+        protected ComponentListener accessibleAWTComponentHandler;
+    
+        protected FocusListener accessibleAWTFocusHandler;
+        */
+        /*
+         * Number of registered property change listeners.
+         */
+        /*
+        int listenersCount;
+
+        public void addFocusListener(FocusListener l) {
+            Component.this.addFocusListener(l);
+        }
+
+        @Override
+        public void addPropertyChangeListener(PropertyChangeListener listener) {
+            toolkit.lockAWT();
+            try {
+                super.addPropertyChangeListener(listener);
+                listenersCount++;
+                if (accessibleAWTComponentHandler == null) {
+                    accessibleAWTComponentHandler = new AccessibleAWTComponentHandler();
+                    Component.this.addComponentListener(accessibleAWTComponentHandler);
+                }
+                if (accessibleAWTFocusHandler == null) {
+                    accessibleAWTFocusHandler = new AccessibleAWTFocusHandler();
+                    Component.this.addFocusListener(accessibleAWTFocusHandler);
+                }
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+        
+        public boolean contains(Point p) {
+            toolkit.lockAWT();
+            try {
+                return Component.this.contains(p);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Accessible getAccessibleAt(Point arg0) {
+            toolkit.lockAWT();
+            try {
+                return null;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Color getBackground() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getBackground();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Rectangle getBounds() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getBounds();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Cursor getCursor() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getCursor();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Font getFont() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getFont();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public FontMetrics getFontMetrics(Font f) {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getFontMetrics(f);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Color getForeground() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getForeground();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Point getLocation() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getLocation();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Point getLocationOnScreen() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getLocationOnScreen();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public Dimension getSize() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getSize();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isEnabled() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isEnabled();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isFocusTraversable() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isFocusTraversable();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isShowing() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isShowing();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public boolean isVisible() {
+            toolkit.lockAWT();
+            try {
+                return Component.this.isVisible();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void removeFocusListener(FocusListener l) {
+            Component.this.removeFocusListener(l);
+        }
+
+        @Override
+        public void removePropertyChangeListener(PropertyChangeListener listener) {
+            toolkit.lockAWT();
+            try {
+                super.removePropertyChangeListener(listener);
+                listenersCount--;
+                if (listenersCount > 0) {
+                    return;
+                }
+                // if there are no more listeners, remove handlers:
+                Component.this.removeFocusListener(accessibleAWTFocusHandler);
+                Component.this.removeComponentListener(accessibleAWTComponentHandler);
+                accessibleAWTComponentHandler = null;
+                accessibleAWTFocusHandler = null;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void requestFocus() {
+            toolkit.lockAWT();
+            try {
+                Component.this.requestFocus();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setBackground(Color color) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setBackground(color);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setBounds(Rectangle r) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setBounds(r);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setCursor(Cursor cursor) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setCursor(cursor);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setEnabled(boolean enabled) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setEnabled(enabled);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setFont(Font f) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setFont(f);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setForeground(Color color) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setForeground(color);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setLocation(Point p) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setLocation(p);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setSize(Dimension size) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setSize(size);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        public void setVisible(boolean visible) {
+            toolkit.lockAWT();
+            try {
+                Component.this.setVisible(visible);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+        
+        @Override
+        public Accessible getAccessibleParent() {
+            toolkit.lockAWT();
+            try {
+                Accessible aParent = super.getAccessibleParent();
+                if (aParent != null) {
+                    return aParent;
+                }
+                Container parent = getParent();
+                return (parent instanceof Accessible ? (Accessible) parent : null);
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public Accessible getAccessibleChild(int i) {
+            toolkit.lockAWT();
+            try {
+                return null;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public int getAccessibleChildrenCount() {
+            toolkit.lockAWT();
+            try {
+                return 0;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleComponent getAccessibleComponent() {
+            return this;
+        }
+
+        @Override
+        public String getAccessibleDescription() {
+            return super.getAccessibleDescription(); // why override?
+        }
+
+        @Override
+        public int getAccessibleIndexInParent() {
+            toolkit.lockAWT();
+            try {
+                if (getAccessibleParent() == null) {
+                    return -1;
+                }
+                int count = 0;
+                Container parent = getParent();
+                for (int i = 0; i < parent.getComponentCount(); i++) {
+                    Component aComp = parent.getComponent(i);
+                    if (aComp instanceof Accessible) {
+                        if (aComp == Component.this) {
+                            return count;
+                        }
+                        ++count;
+                    }
+                }
+                return -1;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleRole getAccessibleRole() {
+            toolkit.lockAWT();
+            try {
+                return AccessibleRole.AWT_COMPONENT;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleStateSet getAccessibleStateSet() {
+            toolkit.lockAWT();
+            try {
+                AccessibleStateSet set = new AccessibleStateSet();
+                if (isEnabled()) {
+                    set.add(AccessibleState.ENABLED);
+                }
+                if (isFocusable()) {
+                    set.add(AccessibleState.FOCUSABLE);
+                }
+                if (hasFocus()) {
+                    set.add(AccessibleState.FOCUSED);
+                }
+                if (isOpaque()) {
+                    set.add(AccessibleState.OPAQUE);
+                }
+                if (isShowing()) {
+                    set.add(AccessibleState.SHOWING);
+                }
+                if (isVisible()) {
+                    set.add(AccessibleState.VISIBLE);
+                }
+                return set;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public Locale getLocale() throws IllegalComponentStateException {
+            toolkit.lockAWT();
+            try {
+                return Component.this.getLocale();
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+    }
+    */
+    /**
+     * The BltBufferStrategy class provides opportunity of blitting 
+     * offscreen surfaces to a component. For more information on 
+     * blitting, see <a href="http://en.wikipedia.org/wiki/Bit_blit">Bit blit</a>.
+     */
+    protected class BltBufferStrategy extends BufferStrategy {
+        
+        /** The back buffers. */
+        protected VolatileImage[] backBuffers;
+
+        /** The caps. */
+        protected BufferCapabilities caps;
+
+        /** The width. */
+        protected int width;
+
+        /** The height. */
+        protected int height;
+
+        /** The validated contents. */
+        protected boolean validatedContents;
+
+        /**
+         * Instantiates a new BltBufferStrategy buffer strategy.
+         * 
+         * @param numBuffers the number of buffers.
+         * @param caps the BufferCapabilities.
+         * 
+         * @throws NotImplementedException the not implemented exception.
+         */
+        protected BltBufferStrategy(int numBuffers, BufferCapabilities caps) throws org.apache.harmony.luni.util.NotImplementedException {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Returns true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics. 
+         * 
+         * @return true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics, false otherwise.
+         *  
+         * @see java.awt.image.BufferStrategy#contentsLost()
+         */
+        @Override
+        public boolean contentsLost() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Returns true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color.
+         * 
+         * @return true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color,
+         * false otherwise.
+         *           
+         * @see java.awt.image.BufferStrategy#contentsRestored()
+         */
+        @Override
+        public boolean contentsRestored() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Creates the back buffers.
+         * 
+         * @param numBuffers the number of buffers.
+         */
+        protected void createBackBuffers(int numBuffers) {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Returns the BufferCapabilities of the buffer strategy.
+         * 
+         * @return the BufferCapabilities.
+         * 
+         * @see java.awt.image.BufferStrategy#getCapabilities()
+         */
+        @Override
+        public BufferCapabilities getCapabilities() {
+            return (BufferCapabilities) caps.clone();
+        }
+
+        /**
+         * Gets Graphics of current buffer strategy.
+         * 
+         * @return the Graphics of current buffer strategy.
+         * 
+         * @see java.awt.image.BufferStrategy#getDrawGraphics()
+         */
+        @Override
+        public Graphics getDrawGraphics() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Revalidates the lost drawing buffer.
+         */
+        protected void revalidate() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Shows the next available buffer.
+         * 
+         * @see java.awt.image.BufferStrategy#show()
+         */
+        @Override
+        public void show() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * The FlipBufferStrategy class is for flipping buffers on a component. 
+     */
+    protected class FlipBufferStrategy extends BufferStrategy {
+        
+        /** The Buffer Capabilities. */
+        protected BufferCapabilities caps;
+
+        /** The drawing buffer. */
+        protected Image drawBuffer;
+
+        /** The drawing VolatileImage buffer. */
+        protected VolatileImage drawVBuffer;
+
+        /** The number of buffers. */
+        protected int numBuffers;
+
+        /** The validated contents indicates if the drawing buffer is restored from
+         * lost state. */
+        protected boolean validatedContents;
+
+        /**
+         * Instantiates a new flip buffer strategy.
+         * 
+         * @param numBuffers the number of buffers.
+         * @param caps the BufferCapabilities.
+         * 
+         * @throws AWTException if the capabilities supplied could not 
+         * be supported or met.
+         */
+        protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
+                throws AWTException {
+            //???AWT
+            /*
+            if (!(Component.this instanceof Window) && !(Component.this instanceof Canvas)) {
+                // awt.14B=Only Canvas or Window is allowed
+                throw new ClassCastException(Messages.getString("awt.14B")); //$NON-NLS-1$
+            }
+            */
+            // TODO: throw new AWTException("Capabilities are not supported");
+            this.numBuffers = numBuffers;
+            this.caps = (BufferCapabilities) caps.clone();
+        }
+
+        /**
+         * Returns true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics. 
+         * 
+         * @return true if the drawing buffer has been lost since the last call 
+         * to getDrawGraphics, false otherwise.
+         * 
+         * @see java.awt.image.BufferStrategy#contentsLost()
+         */
+        @Override
+        public boolean contentsLost() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Returns true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color.
+         * 
+         * @return true if the drawing buffer has been restored from a lost
+         * state and reinitialized to the default background color,
+         * false otherwise. 
+         * 
+         * @see java.awt.image.BufferStrategy#contentsRestored()
+         */
+        @Override
+        public boolean contentsRestored() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return false;
+        }
+
+        /**
+         * Creates flipping buffers with the specified buffer capabilities.
+         * 
+         * @param numBuffers the number of buffers.
+         * @param caps the BufferCapabilities.
+         * 
+         * @throws AWTException if the capabilities could not be 
+         * supported or met.
+         */
+        protected void createBuffers(int numBuffers, BufferCapabilities caps)
+                throws AWTException {
+            if (numBuffers < 2) {
+                // awt.14C=Number of buffers must be greater than one
+                throw new IllegalArgumentException(Messages.getString("awt.14C")); //$NON-NLS-1$
+            }
+            if (!caps.isPageFlipping()) {
+                // awt.14D=Buffer capabilities should support flipping
+                throw new IllegalArgumentException(Messages.getString("awt.14D")); //$NON-NLS-1$
+            }
+            if (!Component.this.behaviour.isDisplayable()) {
+                // awt.14E=Component should be displayable
+                throw new IllegalStateException(Messages.getString("awt.14E")); //$NON-NLS-1$
+            }
+            // TODO: throw new AWTException("Capabilities are not supported");
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Destroy buffers.
+         */
+        protected void destroyBuffers() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Flips the contents of the back buffer to the front buffer.
+         * 
+         * @param flipAction the flip action.
+         */
+        protected void flip(BufferCapabilities.FlipContents flipAction) {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Gets the back buffer as Image.
+         * 
+         * @return the back buffer as Image.
+         */
+        protected Image getBackBuffer() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Returns the BufferCapabilities of the buffer strategy.
+         * 
+         * @return the BufferCapabilities.
+         * 
+         * @see java.awt.image.BufferStrategy#getCapabilities()
+         */
+        @Override
+        public BufferCapabilities getCapabilities() {
+            return (BufferCapabilities) caps.clone();
+        }
+
+        /**
+         * Gets Graphics of current buffer strategy.
+         * 
+         * @return the Graphics of current buffer strategy.
+         * 
+         * @see java.awt.image.BufferStrategy#getDrawGraphics()
+         */
+        @Override
+        public Graphics getDrawGraphics() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+            return null;
+        }
+
+        /**
+         * Revalidates the lost drawing buffer.
+         */
+        protected void revalidate() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+
+        /**
+         * Shows the next available buffer.
+         * 
+         * @see java.awt.image.BufferStrategy#show()
+         */
+        @Override
+        public void show() {
+            if (true) {
+                throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * The internal component's state utilized by the visual theme.
+     */
+    class ComponentState implements State {
+        
+        /** The default minimum size. */
+        private Dimension defaultMinimumSize = new Dimension();
+
+        /**
+         * Checks if the component is enabled.
+         * 
+         * @return true, if the component is enabled
+         */
+        public boolean isEnabled() {
+            return enabled;
+        }
+
+        /**
+         * Checks if the component is visible.
+         * 
+         * @return true, if the component is visible
+         */
+        public boolean isVisible() {
+            return visible;
+        }
+
+        /**
+         * Checks if is focused.
+         * 
+         * @return true, if is focused
+         */
+        public boolean isFocused() {
+            //???AWT: return isFocusOwner();
+            return false;
+        }
+
+        /**
+         * Gets the font.
+         * 
+         * @return the font
+         */
+        public Font getFont() {
+            return Component.this.getFont();
+        }
+
+        /**
+         * Checks if the font has been set.
+         * 
+         * @return true, if the font has been set
+         */
+        public boolean isFontSet() {
+            return font != null;
+        }
+
+        /**
+         * Gets the background color.
+         * 
+         * @return the background color
+         */
+        public Color getBackground() {
+            Color c = Component.this.getBackground();
+            return (c != null) ? c : getDefaultBackground();
+        }
+
+        /**
+         * Checks if the background is set.
+         * 
+         * @return true, if the background is set
+         */
+        public boolean isBackgroundSet() {
+            return backColor != null;
+        }
+
+        /**
+         * Gets the text color.
+         * 
+         * @return the text color
+         */
+        public Color getTextColor() {
+            Color c = getForeground();
+            return (c != null) ? c : getDefaultForeground();
+        }
+
+        /**
+         * Checks if the text color is set.
+         * 
+         * @return true, if the text color is set
+         */
+        public boolean isTextColorSet() {
+            return foreColor != null;
+        }
+
+        /**
+         * Gets the font metrics.
+         * 
+         * @return the font metrics
+         */
+        @SuppressWarnings("deprecation")
+        public FontMetrics getFontMetrics() {
+            return toolkit.getFontMetrics(Component.this.getFont());
+        }
+
+        /**
+         * Gets the bounding rectangle.
+         * 
+         * @return the bounding rectangle
+         */
+        public Rectangle getBounds() {
+            return new Rectangle(x, y, w, h);
+        }
+
+        /**
+         * Gets the size of the bounding rectangle.
+         * 
+         * @return the size of the bounding rectangle
+         */
+        public Dimension getSize() {
+            return new Dimension(w, h);
+        }
+
+        /**
+         * Gets the window id.
+         * 
+         * @return the window id
+         */
+        public long getWindowId() {
+            NativeWindow win = getNativeWindow();
+            return (win != null) ? win.getId() : 0;
+        }
+
+        /**
+         * Gets the default minimum size.
+         * 
+         * @return the default minimum size
+         */
+        public Dimension getDefaultMinimumSize() {
+            if (defaultMinimumSize == null) {
+                calculate();
+            }
+            return defaultMinimumSize;
+        }
+
+        /**
+         * Sets the default minimum size.
+         * 
+         * @param size the new default minimum size
+         */
+        public void setDefaultMinimumSize(Dimension size) {
+            defaultMinimumSize = size;
+        }
+
+        /**
+         * Reset the default minimum size to null.
+         */
+        public void reset() {
+            defaultMinimumSize = null;
+        }
+
+        /**
+         * Calculate the default minimum size: to be overridden.
+         */
+        public void calculate() {
+            // to be overridden
+        }
+    }
+
+    //???AWT: private transient AccessibleContext accessibleContext;
+
+    /** The behaviour. */
+    final transient ComponentBehavior behaviour;
+
+    //???AWT: Container parent;
+
+    /** The name. */
+    private String name;
+
+    /** The auto name. */
+    private boolean autoName = true;
+
+    /** The font. */
+    private Font font;
+
+    /** The back color. */
+    private Color backColor;
+
+    /** The fore color. */
+    private Color foreColor;
+
+    /** The deprecated event handler. */
+    boolean deprecatedEventHandler = true;
+
+    /** The enabled events. */
+    private long enabledEvents;
+
+    /** The enabled awt events. */
+    private long enabledAWTEvents;
+
+    /** The component listeners. */
+    private final AWTListenerList<ComponentListener> componentListeners = new AWTListenerList<ComponentListener>(
+            this);
+
+    /** The focus listeners. */
+    private final AWTListenerList<FocusListener> focusListeners = new AWTListenerList<FocusListener>(
+            this);
+
+    /** The hierarchy listeners. */
+    private final AWTListenerList<HierarchyListener> hierarchyListeners = new AWTListenerList<HierarchyListener>(
+            this);
+
+    /** The hierarchy bounds listeners. */
+    private final AWTListenerList<HierarchyBoundsListener> hierarchyBoundsListeners = new AWTListenerList<HierarchyBoundsListener>(
+            this);
+
+    /** The key listeners. */
+    private final AWTListenerList<KeyListener> keyListeners = new AWTListenerList<KeyListener>(
+            this);
+
+    /** The mouse listeners. */
+    private final AWTListenerList<MouseListener> mouseListeners = new AWTListenerList<MouseListener>(
+            this);
+
+    /** The mouse motion listeners. */
+    private final AWTListenerList<MouseMotionListener> mouseMotionListeners = new AWTListenerList<MouseMotionListener>(
+            this);
+
+    /** The mouse wheel listeners. */
+    private final AWTListenerList<MouseWheelListener> mouseWheelListeners = new AWTListenerList<MouseWheelListener>(
+            this);
+
+    /** The input method listeners. */
+    private final AWTListenerList<InputMethodListener> inputMethodListeners = new AWTListenerList<InputMethodListener>(
+            this);
+
+    /** The x. */
+    int x;
+
+    /** The y. */
+    int y;
+
+    /** The w. */
+    int w;
+
+    /** The h. */
+    int h;
+
+    /** The maximum size. */
+    private Dimension maximumSize;
+
+    /** The minimum size. */
+    private Dimension minimumSize;
+
+    /** The preferred size. */
+    private Dimension preferredSize;
+
+    /** The bounds mask param. */
+    private int boundsMaskParam;
+
+    /** The ignore repaint. */
+    private boolean ignoreRepaint;
+
+    /** The enabled. */
+    private boolean enabled = true;
+
+    /** The input methods enabled. */
+    private boolean inputMethodsEnabled = true;
+
+    /** The dispatch to im. */
+    transient boolean dispatchToIM = true;
+
+    /** The focusable. */
+    private boolean focusable = true; // By default, all Components return
+
+    // true from isFocusable() method
+    /** The visible. */
+    boolean visible = true;
+
+    /** The called set focusable. */
+    private boolean calledSetFocusable;
+
+    /** The overriden is focusable. */
+    private boolean overridenIsFocusable = true;
+
+    /** The focus traversal keys enabled. */
+    private boolean focusTraversalKeysEnabled = true;
+
+    /** Possible keys are: FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, UP_CYCLE_TRAVERSAL_KEYS. */
+    private final Map<Integer, Set<? extends AWTKeyStroke>> traversalKeys = new HashMap<Integer, Set<? extends AWTKeyStroke>>();
+
+    /** The traversal i ds. */
+    int[] traversalIDs;
+
+    /** The locale. */
+    private Locale locale;
+
+    /** The orientation. */
+    private ComponentOrientation orientation;
+
+    /** The property change support. */
+    private PropertyChangeSupport propertyChangeSupport;
+
+    //???AWT: private ArrayList<PopupMenu> popups;
+
+    /** The coalescer. */
+    private boolean coalescer;
+
+    /** The events table. */
+    private Hashtable<Integer, LinkedList<AWTEvent>> eventsTable;
+
+    /** Cashed reference used during EventQueue.postEvent() */
+    private LinkedList<AWTEvent> eventsList;
+
+    /** The hierarchy changing counter. */
+    private int hierarchyChangingCounter;
+
+    /** The was showing. */
+    private boolean wasShowing;
+
+    /** The was displayable. */
+    private boolean wasDisplayable;
+
+    /** The cursor. */
+    Cursor cursor;
+
+    //???AWT: DropTarget dropTarget;
+
+    /** The mouse exited expected. */
+    private boolean mouseExitedExpected;
+
+    /** The repaint region. */
+    transient MultiRectArea repaintRegion;
+
+    //???AWT: transient RedrawManager redrawManager;
+    /** The redraw manager. */
+    transient Object redrawManager;
+
+    /** The valid. */
+    private boolean valid;
+
+    /** The updated images. */
+    private HashMap<Image, ImageParameters> updatedImages;
+
+    /**
+     * The lock object for private component's data which don't affect the
+     * component hierarchy.
+     */
+    private class ComponentLock {
+    }
+
+    /** The component lock. */
+    private final transient Object componentLock = new ComponentLock();
+    static {
+        PrivilegedAction<String[]> action = new PrivilegedAction<String[]>() {
+            public String[] run() {
+                String properties[] = new String[2];
+                properties[0] = System.getProperty("awt.image.redrawrate", "100"); //$NON-NLS-1$ //$NON-NLS-2$
+                properties[1] = System.getProperty("awt.image.incrementaldraw", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+                return properties;
+            }
+        };
+        String properties[] = AccessController.doPrivileged(action);
+        // FIXME: rate is never used, can this code and the get property above
+        // be removed?
+        // int rate;
+        //
+        // try {
+        // rate = Integer.decode(properties[0]).intValue();
+        // } catch (NumberFormatException e) {
+        // rate = 100;
+        // }
+        incrementalImageUpdate = properties[1].equals("true"); //$NON-NLS-1$
+    }
+
+    /**
+     * Instantiates a new component.
+     */
+    protected Component() {
+        toolkit.lockAWT();
+        try {
+            orientation = ComponentOrientation.UNKNOWN;
+            redrawManager = null;
+            //???AWT
+            /*
+            traversalIDs = this instanceof Container ? KeyboardFocusManager.contTraversalIDs
+                    : KeyboardFocusManager.compTraversalIDs;
+            for (int element : traversalIDs) {
+                traversalKeys.put(new Integer(element), null);
+            }
+            behaviour = createBehavior();
+            */
+            behaviour = null;
+            
+            deriveCoalescerFlag();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Determine that the class inherited from Component declares the method
+     * coalesceEvents(), and put the results to the childClassesFlags map.
+     */
+    private void deriveCoalescerFlag() {
+        Class<?> thisClass = getClass();
+        boolean flag = true;
+        synchronized (childClassesFlags) {
+            Boolean flagWrapper = childClassesFlags.get(thisClass);
+            if (flagWrapper == null) {
+                Method coalesceMethod = null;
+                for (Class<?> c = thisClass; c != Component.class; c = c.getSuperclass()) {
+                    try {
+                        coalesceMethod = c.getDeclaredMethod("coalesceEvents", new Class[] { //$NON-NLS-1$
+                                Class.forName("java.awt.AWTEvent"), //$NON-NLS-1$
+                                Class.forName("java.awt.AWTEvent") }); //$NON-NLS-1$
+                    } catch (Exception e) {
+                    }
+                    if (coalesceMethod != null) {
+                        break;
+                    }
+                }
+                flag = (coalesceMethod != null);
+                childClassesFlags.put(thisClass, Boolean.valueOf(flag));
+            } else {
+                flag = flagWrapper.booleanValue();
+            }
+        }
+        coalescer = flag;
+        if (flag) {
+            eventsTable = new Hashtable<Integer, LinkedList<AWTEvent>>();
+        } else {
+            eventsTable = null;
+        }
+    }
+
+    /**
+     * Sets the name of the Component.
+     * 
+     * @param name the new name of the Component.
+     */
+    public void setName(String name) {
+        String oldName;
+        toolkit.lockAWT();
+        try {
+            autoName = false;
+            oldName = this.name;
+            this.name = name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("name", oldName, name); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the name of this Component.
+     * 
+     * @return the name of this Component.
+     */
+    public String getName() {
+        toolkit.lockAWT();
+        try {
+            if ((name == null) && autoName) {
+                name = autoName();
+            }
+            return name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Auto name.
+     * 
+     * @return the string
+     */
+    String autoName() {
+        String name = getClass().getName();
+        if (name.indexOf("$") != -1) { //$NON-NLS-1$
+            return null;
+        }
+        //???AWT
+        //int number = toolkit.autoNumber.nextComponent++;
+        int number = 0;
+        name = name.substring(name.lastIndexOf(".") + 1) + Integer.toString(number); //$NON-NLS-1$
+        return name;
+    }
+
+    /**
+     * Returns the string representation of the Component.
+     * 
+     * @return the string representation of the Component.
+     */
+    @Override
+    public String toString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code:
+         * 
+         * Component c = new Component(){}; c.setVisible(false);
+         * System.out.println(c);
+         */
+        toolkit.lockAWT();
+        try {
+            return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    public void add(PopupMenu popup) {
+        toolkit.lockAWT();
+        try {
+            if (popup.getParent() == this) {
+                return;
+            }
+            if (popups == null) {
+                popups = new ArrayList<PopupMenu>();
+            }
+            popup.setParent(this);
+            popups.add(popup);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Returns true, if the component contains the specified Point.
+     * 
+     * @param p the Point.
+     * 
+     * @return true, if the component contains the specified Point,
+     * false otherwise.
+     */
+    public boolean contains(Point p) {
+        toolkit.lockAWT();
+        try {
+            return contains(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true, if the component contains the point with 
+     * the specified coordinates.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if the component contains the point with 
+     * the specified coordinates, false otherwise.
+     */
+    public boolean contains(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return inside(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by replaced by getSize() method.
+     * 
+     * @return the dimension.
+     * 
+     * @deprecated Replaced by getSize() method.
+     */
+    @Deprecated
+    public Dimension size() {
+        toolkit.lockAWT();
+        try {
+            return new Dimension(w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    
+    //???AWT
+    /*
+    public Container getParent() {
+        toolkit.lockAWT();
+        try {
+            return parent;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * List.
+     * 
+     * @param out the out
+     * @param indent the indent
+     * 
+     * @return the nearest heavyweight ancestor in hierarchy or
+     * <code>null</code> if not found
+     */
+    //???AWT
+    /*
+    Component getHWAncestor() {
+        return (parent != null ? parent.getHWSurface() : null);
+    }
+    */
+    
+    /**
+     * @return heavyweight component that is equal to or is a nearest
+     *         heavyweight container of the current component, or
+     *         <code>null</code> if not found
+     */
+    //???AWT
+    /*
+    Component getHWSurface() {
+        Component parent;
+        for (parent = this; (parent != null) && (parent.isLightweight()); parent = parent
+                .getParent()) {
+            ;
+        }
+        return parent;
+    }
+
+    Window getWindowAncestor() {
+        Component par;
+        for (par = this; par != null && !(par instanceof Window); par = par.getParent()) {
+            ;
+        }
+        return (Window) par;
+    }
+    */
+    
+    /** To be called by container */
+    //???AWT
+    /*
+    void setParent(Container parent) {
+        this.parent = parent;
+        setRedrawManager();
+    }
+
+    void setRedrawManager() {
+        redrawManager = getRedrawManager();
+    }
+
+    public void remove(MenuComponent menu) {
+        toolkit.lockAWT();
+        try {
+            if (menu.getParent() == this) {
+                menu.setParent(null);
+                popups.remove(menu);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    /**
+     * Prints a list of this component with the specified number of 
+     * leading whitespace characters to the specified PrintStream.
+     * 
+     * @param out the output PrintStream object.
+     * @param indent how many leading whitespace characters to prepend
+     */
+    public void list(PrintStream out, int indent) {
+        toolkit.lockAWT();
+        try {
+            out.println(getIndentStr(indent) + this);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component to the specified PrintWriter.
+     * 
+     * @param out the output PrintWriter object.
+     */
+    public void list(PrintWriter out) {
+        toolkit.lockAWT();
+        try {
+            list(out, 1);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component with the specified number of 
+     * leading whitespace characters to the specified PrintWriter.
+     * 
+     * @param out the output PrintWriter object.
+     * @param indent how many leading whitespace characters to prepend
+     */
+    public void list(PrintWriter out, int indent) {
+        toolkit.lockAWT();
+        try {
+            out.println(getIndentStr(indent) + this);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets a string composed of the desired number of 
+     * whitespace characters.
+     * 
+     * @param indent the length of the String to return
+     * 
+     * @return the string composed of the desired number of 
+     * whitespace characters
+     */
+    String getIndentStr(int indent) {
+        char[] ind = new char[indent];
+        for (int i = 0; i < indent; ind[i++] = ' ') {
+            ;
+        }
+        return new String(ind);
+    }
+
+    /**
+     * Prints a list of this component to the specified PrintStream
+     * 
+     * @param out the output PrintStream object.
+     */
+    public void list(PrintStream out) {
+        toolkit.lockAWT();
+        try {
+            // default indent = 1
+            list(out, 1);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints a list of this component to the standard system 
+     * output stream.
+     */
+    public void list() {
+        toolkit.lockAWT();
+        try {
+            list(System.out);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints this component. 
+     * 
+     * @param g the Graphics to be used for painting. 
+     */
+    public void print(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prints the component and all of its subcomponents.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    public void printAll(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paintAll(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the size of the Component specified by width and height
+     * parameters.
+     * 
+     * @param width the width of the Component.
+     * @param height the height of the Component.
+     */
+    public void setSize(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            resize(width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the size of the Component specified by Dimension object.
+     * 
+     * @param d the new size of the Component.
+     */
+    public void setSize(Dimension d) {
+        toolkit.lockAWT();
+        try {
+            resize(d);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setSize(int, int) method.
+     * 
+     * @param width the width.
+     * @param height the height.
+     * 
+     * @deprecated Replaced by setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            boundsMaskParam = NativeWindow.BOUNDS_NOMOVE;
+            setBounds(x, y, width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setSize(int, int) method.
+     * 
+     * @param size the size.
+     * 
+     * @deprecated Replaced by setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(Dimension size) {
+        toolkit.lockAWT();
+        try {
+            setSize(size.width, size.height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this component is completely opaque.
+     * 
+     * @return true, if this component is completely opaque, 
+     *  false by default.
+     */
+    public boolean isOpaque() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isOpaque();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Disables.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method.
+     */
+    @Deprecated
+    public void disable() {
+        toolkit.lockAWT();
+        try {
+            setEnabledImpl(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        //???AWT: fireAccessibleStateChange(AccessibleState.ENABLED, false);
+    }
+
+    /**
+     * Enables this component.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method.
+     */
+    @Deprecated
+    public void enable() {
+        toolkit.lockAWT();
+        try {
+            setEnabledImpl(true);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        //???AWT: fireAccessibleStateChange(AccessibleState.ENABLED, true);
+    }
+
+    /**
+     * Enables or disable this component.
+     * 
+     * @param b the boolean parameter.
+     * 
+     * @deprecated Replaced by setEnabled(boolean) method. 
+     */
+    @Deprecated
+    public void enable(boolean b) {
+        toolkit.lockAWT();
+        try {
+            if (b) {
+                enable();
+            } else {
+                disable();
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Stores the location of this component to the specified Point object;
+     * returns the point of the component's top-left corner.
+     * 
+     * @param rv the Point object where the component's top-left corner
+     * position will be stored.
+     * 
+     * @return the Point which specifies the component's top-left corner.
+     */
+    public Point getLocation(Point rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Point();
+            }
+            rv.setLocation(getX(), getY());
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the location of this component on the form;
+     * returns the point of the component's top-left corner.
+     * 
+     * @return the Point which specifies the component's top-left corner.
+     */
+    public Point getLocation() {
+        toolkit.lockAWT();
+        try {
+            return location();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the size of this Component.
+     * 
+     * @return the size of this Component.
+     */
+    public Dimension getSize() {
+        toolkit.lockAWT();
+        try {
+            return size();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Stores the size of this Component to the specified Dimension 
+     * object.
+     * 
+     * @param rv the Dimension object where the size of the Component 
+     * will be stored.
+     * 
+     * @return the Dimension of this Component.
+     */
+    public Dimension getSize(Dimension rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Dimension();
+            }
+            rv.setSize(getWidth(), getHeight());
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is valid. A component is valid 
+     * if it is correctly sized and positioned within its parent container
+     *  and all its children are also valid. 
+     * 
+     * @return true, if the Component is valid, false otherwise.
+     */
+    public boolean isValid() {
+        toolkit.lockAWT();
+        try {
+            return valid && behaviour.isDisplayable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getComponentAt(int, int) method.
+     * 
+     * @return the Point.
+     * 
+     * @deprecated Replaced by getComponentAt(int, int) method.
+     */
+    @Deprecated
+    public Point location() {
+        toolkit.lockAWT();
+        try {
+            return new Point(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Connects this Component to a native screen resource and makes it 
+     * displayable. This method not be called directly by user applications.
+     */
+    public void addNotify() {
+        toolkit.lockAWT();
+        try {
+            prepare4HierarchyChange();
+            behaviour.addNotify();
+            //???AWT
+//            finishHierarchyChange(this, parent, 0);
+//            if (dropTarget != null) {
+//                dropTarget.addNotify(peer);
+//            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Map to display.
+     * 
+     * @param b the b
+     */
+    void mapToDisplay(boolean b) {
+        //???AWT
+        /*
+        if (b && !isDisplayable()) {
+            if ((this instanceof Window) || ((parent != null) && parent.isDisplayable())) {
+                addNotify();
+            }
+        } else if (!b && isDisplayable()) {
+            removeNotify();
+        }
+        */
+    }
+
+    /**
+     * Gets the toolkit.
+     * 
+     * @return accessible context specific for particular component
+     */
+    //???AWT
+    /*
+    AccessibleContext createAccessibleContext() {
+        return null;
+    }
+
+    public AccessibleContext getAccessibleContext() {
+        toolkit.lockAWT();
+        try {
+            if (accessibleContext == null) {
+                accessibleContext = createAccessibleContext();
+            }
+            return accessibleContext;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+ 
+    /**
+     * Gets Toolkit for the current Component.
+     * 
+     * @return the Toolkit of this Component.
+     */
+    public Toolkit getToolkit() {
+        return toolkit;
+    }
+
+    /**
+     * Gets this component's locking object for AWT component tree 
+     * and layout operations.
+     * 
+     * @return the tree locking object.
+     */
+    public final Object getTreeLock() {
+        return toolkit.awtTreeLock;
+    }
+
+    /**
+     * @param evt the Event.
+     * @param what the event's key.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Use ActionListener class for registering event listener.   
+     */
+    @Deprecated
+    public boolean action(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+
+    /**
+     * Gets the property change support.
+     * 
+     * @return the property change support
+     */
+    private PropertyChangeSupport getPropertyChangeSupport() {
+        synchronized (componentLock) {
+            if (propertyChangeSupport == null) {
+                propertyChangeSupport = new PropertyChangeSupport(this);
+            }
+            return propertyChangeSupport;
+        }
+    }
+    
+    //???AWT
+    /*
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        getPropertyChangeSupport().addPropertyChangeListener(listener);
+    }
+
+    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+        getPropertyChangeSupport().addPropertyChangeListener(propertyName, listener);
+    }
+
+    public void applyComponentOrientation(ComponentOrientation orientation) {
+        toolkit.lockAWT();
+        try {
+            setComponentOrientation(orientation);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Returns true if the set of focus traversal keys for the given focus 
+     * traversal operation has been explicitly defined for this Component. 
+     * 
+     * @param id the ID of traversal key.
+     * 
+     * @return true, if the set of focus traversal keys for the given focus 
+     * traversal operation has been explicitly defined for this Component,
+     * false otherwise. 
+     */
+    public boolean areFocusTraversalKeysSet(int id) {
+        toolkit.lockAWT();
+        try {
+            Integer Id = new Integer(id);
+            if (traversalKeys.containsKey(Id)) {
+                return traversalKeys.get(Id) != null;
+            }
+            // awt.14F=invalid focus traversal key identifier
+            throw new IllegalArgumentException(Messages.getString("awt.14F")); //$NON-NLS-1$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the bounds of the Component.
+     * 
+     * @return the rectangle bounds of the Component.
+     * 
+     * @deprecated Use getBounds() methood.
+     */
+    @Deprecated
+    public Rectangle bounds() {
+        toolkit.lockAWT();
+        try {
+            return new Rectangle(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the construction status of a specified image
+     * with the specified width and height that is being created.
+     * 
+     * 
+     * @param image the image to be checked.
+     * @param width the width of scaled image which status is being checked, or -1.
+     * @param height the height of scaled image which status is being checked, or -1.
+     * @param observer the ImageObserver object to be notified while 
+     * the image is being prepared.
+     * 
+     * @return the ImageObserver flags of the current state of the image data.
+     */
+    public int checkImage(Image image, int width, int height, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.checkImage(image, width, height, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the construction status of a specified image that is being created.
+     * 
+     * 
+     * @param image the image to be checked.
+     * @param observer the ImageObserver object to be notified while 
+     * the image is being prepared.
+     * 
+     * @return the ImageObserver flags of the current state of the image data.
+     */
+    public int checkImage(Image image, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.checkImage(image, -1, -1, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Coalesces the existed event with new event.
+     * 
+     * @param existingEvent the existing event in the EventQueue.
+     * @param newEvent the new event to be posted to the EventQueue.
+     * 
+     * @return the coalesced AWTEvent, or null if there is no coalescing done. 
+     */
+    protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent) {
+        toolkit.lockAWT();
+        try {
+            // Nothing to do:
+            // 1. Mouse events coalesced at WTK level
+            // 2. Paint events handled by RedrawManager
+            // This method is for overriding only
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if this Component is a coalescer.
+     * 
+     * @return true, if is coalescer
+     */
+    boolean isCoalescer() {
+        return coalescer;
+    }
+
+    /**
+     * Gets the relative event.
+     * 
+     * @param id the id
+     * 
+     * @return the relative event
+     */
+    AWTEvent getRelativeEvent(int id) {
+        Integer idWrapper = new Integer(id);
+        eventsList = eventsTable.get(idWrapper);
+        if (eventsList == null) {
+            eventsList = new LinkedList<AWTEvent>();
+            eventsTable.put(idWrapper, eventsList);
+            return null;
+        }
+        if (eventsList.isEmpty()) {
+            return null;
+        }
+        return eventsList.getLast();
+    }
+
+    /**
+     * Adds the new event.
+     * 
+     * @param event the event
+     */
+    void addNewEvent(AWTEvent event) {
+        eventsList.addLast(event);
+    }
+
+    /**
+     * Removes the relative event.
+     */
+    void removeRelativeEvent() {
+        eventsList.removeLast();
+    }
+
+    /**
+     * Removes the next event.
+     * 
+     * @param id the id
+     */
+    void removeNextEvent(int id) {
+        eventsTable.get(new Integer(id)).removeFirst();
+    }
+
+    /**
+     * Creates the image with the specified ImageProducer.
+     * 
+     * @param producer the ImageProducer to be used for image creation.
+     * 
+     * @return the image with the specified ImageProducer.
+     */
+    public Image createImage(ImageProducer producer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.createImage(producer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates an off-screen drawable image to be used for double buffering.
+     * 
+     * @param width the width of the image.
+     * @param height the height of the image.
+     * 
+     * @return the off-screen drawable image or null if the component is not 
+     * displayable or GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public Image createImage(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            ColorModel cm = gc.getColorModel(Transparency.OPAQUE);
+            WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
+            Image image = new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates an off-screen drawable image with the specified width,
+     * height and ImageCapabilities.
+     * 
+     * @param width the width
+     * @param height the height
+     * @param caps the ImageCapabilities.
+     * 
+     * @return the volatile image
+     * 
+     * @throws AWTException if an image with the specified capabilities 
+     * cannot be created.
+     */
+    public VolatileImage createVolatileImage(int width, int height, ImageCapabilities caps)
+            throws AWTException {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            VolatileImage image = gc.createCompatibleVolatileImage(width, height, caps);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Creates a volatile off-screen drawable image which is used 
+     * for double buffering.
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * 
+     * @return the volatile image a volatile off-screen drawable image 
+     * which is used for double buffering or null if the component 
+     * is not displayable, or GraphicsEnvironment.isHeadless() method
+     * returns true.
+     */
+    public VolatileImage createVolatileImage(int width, int height) {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            GraphicsConfiguration gc = getGraphicsConfiguration();
+            if (gc == null) {
+                return null;
+            }
+            VolatileImage image = gc.createCompatibleVolatileImage(width, height);
+            fillImageBackground(image, width, height);
+            return image;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Fill the image being created by createImage() or createVolatileImage()
+     * with the component's background color to prepare it for double-buffered
+     * painting.
+     * 
+     * @param image the image
+     * @param width the width
+     * @param height the height
+     */
+    private void fillImageBackground(Image image, int width, int height) {
+        Graphics gr = image.getGraphics();
+        gr.setColor(getBackground());
+        gr.fillRect(0, 0, width, height);
+        gr.dispose();
+    }
+
+    /**
+     * Delivers event.
+     * 
+     * @param evt the event.
+     * 
+     * @deprecated Replaced by dispatchEvent(AWTEvent e) method.
+     */
+    @Deprecated
+    public void deliverEvent(Event evt) {
+        postEvent(evt);
+    }
+
+    /**
+     * Prompts the layout manager to lay out this component. 
+     */
+    public void doLayout() {
+        toolkit.lockAWT();
+        try {
+            layout();
+        } finally {
+            toolkit.unlockAWT();
+        }
+        // Implemented in Container
+    }
+
+    /**
+     * Fire property change impl.
+     * 
+     * @param propertyName the property name
+     * @param oldValue the old value
+     * @param newValue the new value
+     */
+    private void firePropertyChangeImpl(String propertyName, Object oldValue, Object newValue) {
+        PropertyChangeSupport pcs;
+        synchronized (componentLock) {
+            if (propertyChangeSupport == null) {
+                return;
+            }
+            pcs = propertyChangeSupport;
+        }
+        pcs.firePropertyChange(propertyName, oldValue, newValue);
+    }
+
+    /**
+     * Reports a bound property changes for int properties.
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    protected void firePropertyChange(String propertyName, int oldValue, int newValue) {
+        firePropertyChangeImpl(propertyName, new Integer(oldValue), new Integer(newValue));
+    }
+
+    /**
+     * Report a bound property change for a boolean-valued property. 
+     *  
+     * @param propertyName the property name.
+     * @param oldValue the property's old value.
+     * @param newValue the property's new value.
+     */
+    protected void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
+        firePropertyChangeImpl(propertyName, Boolean.valueOf(oldValue), Boolean
+                .valueOf(newValue));
+    }
+
+    /**
+     * Reports a bound property change for an Object-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the property's old value
+     * @param newValue the property's new value
+     */
+    protected void firePropertyChange(final String propertyName, final Object oldValue,
+            final Object newValue) {
+        firePropertyChangeImpl(propertyName, oldValue, newValue);
+    }
+
+    /**
+     * Report a bound property change for a byte-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the property's old value.
+     * @param newValue the property's new value.
+     */
+    public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
+        firePropertyChangeImpl(propertyName, new Byte(oldValue), new Byte(newValue));
+    }
+
+    /**
+     * Report a bound property change for a char-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, char oldValue, char newValue) {
+        firePropertyChangeImpl(propertyName, new Character(oldValue), new Character(newValue));
+    }
+
+    /**
+     * Report a bound property change for a short-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, short oldValue, short newValue) {
+        firePropertyChangeImpl(propertyName, new Short(oldValue), new Short(newValue));
+    }
+
+    /**
+     * Report a bound property change for a long-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, long oldValue, long newValue) {
+        firePropertyChangeImpl(propertyName, new Long(oldValue), new Long(newValue));
+    }
+
+    /**
+     * Report a bound property change for a float-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, float oldValue, float newValue) {
+        firePropertyChangeImpl(propertyName, new Float(oldValue), new Float(newValue));
+    }
+
+    /**
+     * Report a bound property change for a double-valued property. 
+     * 
+     * @param propertyName the property name.
+     * @param oldValue the old property's value.
+     * @param newValue the new property's value.
+     */
+    public void firePropertyChange(String propertyName, double oldValue, double newValue) {
+        firePropertyChangeImpl(propertyName, new Double(oldValue), new Double(newValue));
+    }
+
+    /**
+     * Gets the alignment along the x axis. 
+     * 
+     * @return the alignment along the x axis. 
+     */
+    public float getAlignmentX() {
+        toolkit.lockAWT();
+        try {
+            return CENTER_ALIGNMENT;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the alignment along the y axis. 
+     * 
+     * @return the alignment along y axis.
+     */
+    public float getAlignmentY() {
+        toolkit.lockAWT();
+        try {
+            return CENTER_ALIGNMENT;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the background color for this component.
+     * 
+     * @return the background color for this component.
+     */
+    public Color getBackground() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if ((backColor == null) && (parent != null)) {
+                return parent.getBackground();
+            }
+            */
+            return backColor;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the bounding rectangle of this component.
+     * 
+     * @return the bounding rectangle of this component.
+     */
+    public Rectangle getBounds() {
+        toolkit.lockAWT();
+        try {
+            return bounds();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Writes the data of the bounding rectangle to the specified 
+     * Rectangle object.
+     * 
+     * @param rv the Rectangle object where the bounding rectangle's data is stored.  
+     * 
+     * @return the bounding rectangle.
+     */
+    public Rectangle getBounds(Rectangle rv) {
+        toolkit.lockAWT();
+        try {
+            if (rv == null) {
+                rv = new Rectangle();
+            }
+            rv.setBounds(x, y, w, h);
+            return rv;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the color model of the Component.
+     * 
+     * @return the color model of the Component.
+     */
+    public ColorModel getColorModel() {
+        toolkit.lockAWT();
+        try {
+            return getToolkit().getColorModel();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Component which contains the specified Point.
+     * 
+     * @param p the Point.
+     * 
+     * @return the Component which contains the specified Point.
+     */
+    public Component getComponentAt(Point p) {
+        toolkit.lockAWT();
+        try {
+            return getComponentAt(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Component which contains the point with the
+     * specified coordinates.
+     * 
+     * @param x the x coordinate of the point.
+     * @param y the y coordinate of the point.
+     * 
+     * @return the Component which contains the point with the
+     * specified coordinates.
+     */
+    public Component getComponentAt(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return locate(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the component's orientation.
+     * 
+     * @return the component's orientation.
+     */
+    public ComponentOrientation getComponentOrientation() {
+        toolkit.lockAWT();
+        try {
+            return orientation;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the cursor of the Component.
+     * 
+     * @return the Cursor.
+     */
+    public Cursor getCursor() {
+        toolkit.lockAWT();
+        try {
+            if (cursor != null) {
+                return cursor;
+            //???AWT
+            /*
+            } else if (parent != null) {
+                return parent.getCursor();
+            */
+            }
+            return Cursor.getDefaultCursor();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    public DropTarget getDropTarget() {
+        toolkit.lockAWT();
+        try {
+            return dropTarget;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    
+    public Container getFocusCycleRootAncestor() {
+        toolkit.lockAWT();
+        try {
+            for (Container c = parent; c != null; c = c.getParent()) {
+                if (c.isFocusCycleRoot()) {
+                    return c;
+                }
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
+        toolkit.lockAWT();
+        try {
+            Integer kId = new Integer(id);
+            KeyboardFocusManager.checkTraversalKeysID(traversalKeys, kId);
+            Set<? extends AWTKeyStroke> keys = traversalKeys.get(kId);
+            if (keys == null && parent != null) {
+                keys = parent.getFocusTraversalKeys(id);
+            }
+            if (keys == null) {
+                keys = KeyboardFocusManager.getCurrentKeyboardFocusManager()
+                        .getDefaultFocusTraversalKeys(id);
+            }
+            return (Set<AWTKeyStroke>) keys;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * Checks if the the focus traversal keys are enabled for this component.
+     * 
+     * @return true, if the the focus traversal keys are enabled for 
+     * this component, false otherwise.
+     */
+    public boolean getFocusTraversalKeysEnabled() {
+        toolkit.lockAWT();
+        try {
+            return focusTraversalKeysEnabled;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the font metrics of the specified Font.
+     * 
+     * @param f the Font.
+     * 
+     * @return the FontMetrics of the specified Font.
+     */
+    @SuppressWarnings("deprecation")
+    public FontMetrics getFontMetrics(Font f) {
+        return toolkit.getFontMetrics(f);
+    }
+
+    /**
+     * Gets the foreground color of the Component.
+     * 
+     * @return the foreground color of the Component.
+     */
+    public Color getForeground() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if (foreColor == null && parent != null) {
+                return parent.getForeground();
+            }
+            */
+            return foreColor;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Graphics of the Component or null if this Component
+     * is not displayable.
+     * 
+     * @return the Graphics of the Component or null if this Component
+     * is not displayable.
+     */
+    public Graphics getGraphics() {
+        toolkit.lockAWT();
+        try {
+            if (!isDisplayable()) {
+                return null;
+            }
+            Graphics g = behaviour.getGraphics(0, 0, w, h);
+            g.setColor(foreColor);
+            g.setFont(font);
+            return g;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+
+    /**
+     * Gets the GraphicsConfiguration associated with this Component.
+     * 
+     * @return the GraphicsConfiguration associated with this Component.
+     */
+    public GraphicsConfiguration getGraphicsConfiguration() {
+        //???AWT
+        /*
+        toolkit.lockAWT();
+        try {
+            Window win = getWindowAncestor();
+            if (win == null) {
+                return null;
+            }
+            return win.getGraphicsConfiguration();
+        } finally {
+            toolkit.unlockAWT();
+        }
+        */
+        return null;
+    }
+
+    /**
+     * Gets the height of the Component.
+     * 
+     * @return the height of the Component.
+     */
+    public int getHeight() {
+        toolkit.lockAWT();
+        try {
+            return h;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true if paint messages received from the operating system 
+     * should be ignored.
+     * 
+     * @return true if paint messages received from the operating system 
+     * should be ignored, false otherwise.
+     */
+    public boolean getIgnoreRepaint() {
+        toolkit.lockAWT();
+        try {
+            return ignoreRepaint;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the input context of this component for handling 
+     * the communication with input methods when text is entered 
+     * in this component.
+     * 
+     * @return the InputContext used by this Component or 
+     * null if no context is specifined.
+     */
+    public InputContext getInputContext() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            Container parent = getParent();
+            if (parent != null) {
+                return parent.getInputContext();
+            }
+            */
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the input method request handler which supports requests
+     * from input methods for this component, or null for default.
+     * 
+     * @return the input method request handler which supports requests
+     * from input methods for this component, or null for default.
+     */
+    public InputMethodRequests getInputMethodRequests() {
+        return null;
+    }
+
+    /**
+     * Gets the locale of this Component.
+     * 
+     * @return the locale of this Component.
+     */
+    public Locale getLocale() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if (locale == null) {
+                if (parent == null) {
+                    if (this instanceof Window) {
+                        return Locale.getDefault();
+                    }
+                    // awt.150=no parent
+                    throw new IllegalComponentStateException(Messages.getString("awt.150")); //$NON-NLS-1$
+                }
+                return getParent().getLocale();
+            }
+            */
+            return locale;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the location of this component in the form of a point 
+     * specifying the component's top-left corner in the 
+     * screen's coordinate space.
+     * 
+     * @return the Point giving the component's location in the 
+     * screen's coordinate space.
+     * 
+     * @throws IllegalComponentStateException if the component is 
+     * not shown on the screen.
+     */
+    public Point getLocationOnScreen() throws IllegalComponentStateException {
+        toolkit.lockAWT();
+        try {
+            Point p = new Point();
+            if (isShowing()) {
+                //???AWT
+                /*
+                Component comp;
+                for (comp = this; comp != null && !(comp instanceof Window); comp = comp
+                        .getParent()) {
+                    p.translate(comp.getX(), comp.getY());
+                }
+                if (comp instanceof Window) {
+                    p.translate(comp.getX(), comp.getY());
+                }
+                */
+                return p;
+            }
+            // awt.151=component must be showing on the screen to determine its location
+            throw new IllegalComponentStateException(Messages.getString("awt.151")); //$NON-NLS-1$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the peer. This method should not be called directly by
+     * user applications.
+     * 
+     * @return the ComponentPeer.
+     * 
+     * @deprecated Replaced by isDisplayable().
+     */
+    @Deprecated
+    public ComponentPeer getPeer() {
+        toolkit.lockAWT();
+        try {
+            if (behaviour.isDisplayable()) {
+                return peer;
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets an array of the property change listeners registered to
+     * this Component.
+     * 
+     * @return an array of the PropertyChangeListeners registered to
+     * this Component.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        return getPropertyChangeSupport().getPropertyChangeListeners();
+    }
+
+    /**
+     * Gets an array of PropertyChangeListener objects registered
+     * to this Component for the specified property.
+     * 
+     * @param propertyName the property name.
+     * 
+     * @return an array of PropertyChangeListener objects registered
+     * to this Component for the specified property.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
+        return getPropertyChangeSupport().getPropertyChangeListeners(propertyName);
+    }
+
+    /**
+     * Gets the width of the Component.
+     * 
+     * @return the width of the Component.
+     */
+    public int getWidth() {
+        toolkit.lockAWT();
+        try {
+            return w;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the x coordinate of the component's top-left corner.
+     * 
+     * @return the x coordinate of the component's top-left corner.
+     */
+    public int getX() {
+        toolkit.lockAWT();
+        try {
+            return x;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the y coordinate of the component's top-left corner.
+     * 
+     * @return the y coordinate of the component's top-left corner.
+     */
+    public int getY() {
+        toolkit.lockAWT();
+        try {
+            return y;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Got the focus.
+     * 
+     * @param evt the Event.
+     * @param what the Object.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processFocusEvent(FocusEvent) method.
+     */
+    @Deprecated
+    public boolean gotFocus(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Handles event.
+     * 
+     * @param evt the Event.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processEvent(AWTEvent) method.
+     */
+    @Deprecated
+    public boolean handleEvent(Event evt) {
+        switch (evt.id) {
+            case Event.ACTION_EVENT:
+                return action(evt, evt.arg);
+            case Event.GOT_FOCUS:
+                return gotFocus(evt, null);
+            case Event.LOST_FOCUS:
+                return lostFocus(evt, null);
+            case Event.MOUSE_DOWN:
+                return mouseDown(evt, evt.x, evt.y);
+            case Event.MOUSE_DRAG:
+                return mouseDrag(evt, evt.x, evt.y);
+            case Event.MOUSE_ENTER:
+                return mouseEnter(evt, evt.x, evt.y);
+            case Event.MOUSE_EXIT:
+                return mouseExit(evt, evt.x, evt.y);
+            case Event.MOUSE_MOVE:
+                return mouseMove(evt, evt.x, evt.y);
+            case Event.MOUSE_UP:
+                return mouseUp(evt, evt.x, evt.y);
+            case Event.KEY_ACTION:
+            case Event.KEY_PRESS:
+                return keyDown(evt, evt.key);
+            case Event.KEY_ACTION_RELEASE:
+            case Event.KEY_RELEASE:
+                return keyUp(evt, evt.key);
+        }
+        return false;// event not handled
+    }
+
+    /**
+     * Checks whether the Component is the focus owner or not.
+     * 
+     * @return true, if the Component is the focus owner, false otherwise.
+     */
+    public boolean hasFocus() {
+        toolkit.lockAWT();
+        try {
+            //???AWT: return isFocusOwner();
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Hides the Component.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void hide() {
+        toolkit.lockAWT();
+        try {
+            if (!visible) {
+                return;
+            }
+            prepare4HierarchyChange();
+            visible = false;
+            moveFocusOnHide();
+            behaviour.setVisible(false);
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_HIDDEN));
+            //???AWT: finishHierarchyChange(this, parent, 0);
+            notifyInputMethod(null);
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the point with the specified coordinates 
+     * belongs to the Commponent.
+     * 
+     * @param x the x coordinate of the Point.
+     * @param y the y coordinate of the Point.
+     * 
+     * @return true, if the point with the specified coordinates 
+     * belongs to the Commponent, false otherwise.
+     * 
+     * @deprecated Replaced by contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Invalidates the component, this component and all parents 
+     * above it are marked as needing to be laid out. 
+     */
+    public void invalidate() {
+        toolkit.lockAWT();
+        try {
+            valid = false;
+            resetDefaultSize();
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the background color is set to this Component.
+     * 
+     * @return true, if the background color is set to this Component,
+     * false otherwise.
+     */
+    public boolean isBackgroundSet() {
+        toolkit.lockAWT();
+        try {
+            return backColor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not a cursor is set for the Component.
+     * 
+     * @return true, if a cursor is set for the Component,
+     * false otherwise.
+     */
+    public boolean isCursorSet() {
+        toolkit.lockAWT();
+        try {
+            return cursor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is displayable.
+     * 
+     * @return true, if this Component is displayable, false otherwise.
+     */
+    public boolean isDisplayable() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isDisplayable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this component is painted to an buffer
+     * which is copied to the screen later.
+     * 
+     * @return true, if this component is painted to an buffer
+     * which is copied to the screen later, false otherwise.
+     */
+    public boolean isDoubleBuffered() {
+        toolkit.lockAWT();
+        try {
+            // false by default
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not this Component is enabled.
+     * 
+     * @return true, if this Component is enabled, false otherwise.
+     */
+    public boolean isEnabled() {
+        toolkit.lockAWT();
+        try {
+            return enabled;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * "Recursive" isEnabled().
+     * 
+     * @return true if not only component itself is enabled but its heavyweight
+     * parent is also "indirectly" enabled
+     */
+    boolean isIndirectlyEnabled() {
+        Component comp = this;
+        while (comp != null) {
+            if (!comp.isLightweight() && !comp.isEnabled()) {
+                return false;
+            }
+            //???AWT: comp = comp.getRealParent();
+        }
+        return true;
+    }
+
+    /**
+     * Checks if the component is key enabled.
+     * 
+     * @return true, if the component is enabled and indirectly enabled
+     */
+    boolean isKeyEnabled() {
+        if (!isEnabled()) {
+            return false;
+        }
+        return isIndirectlyEnabled();
+    }
+
+    /**
+     * Gets only parent of a child component, but not owner of a window.
+     * 
+     * @return parent of child component, null if component is a top-level
+     * (Window instance)
+     */
+    //???AWT
+    /*
+    Container getRealParent() {
+        return (!(this instanceof Window) ? getParent() : null);
+    }
+
+    public boolean isFocusCycleRoot(Container container) {
+        toolkit.lockAWT();
+        try {
+            return getFocusCycleRootAncestor() == container;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    public boolean isFocusOwner() {
+        toolkit.lockAWT();
+        try {
+            return KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == this;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * Checks whether or not this Component can be focusable.
+     * 
+     * @return true, if this Component can be focusable, false otherwise.
+     * 
+     * @deprecated Replaced by isFocusable(). 
+     */
+    @Deprecated
+    public boolean isFocusTraversable() {
+        toolkit.lockAWT();
+        try {
+            overridenIsFocusable = false;
+            return focusable; // a Component must either be both focusable and
+            // focus traversable, or neither
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if this Component can be focusable or not.
+     * 
+     * @return true, if this Component can be focusable, false otherwise.
+     */
+    public boolean isFocusable() {
+        toolkit.lockAWT();
+        try {
+            return isFocusTraversable();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if the Font is set for this Component or not.
+     * 
+     * @return true, if the Font is set, false otherwise.
+     */
+    public boolean isFontSet() {
+        toolkit.lockAWT();
+        try {
+            return font != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if foreground color is set for the Component or not.
+     * 
+     * @return true, if is foreground color is set for the Component,
+     * false otherwise.
+     */
+    public boolean isForegroundSet() {
+        toolkit.lockAWT();
+        try {
+            return foreColor != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns true if this component has a lightweight peer.
+     * 
+     * @return true, if this component has a lightweight peer,
+     * false if it has a native peer or no peer.
+     */
+    public boolean isLightweight() {
+        toolkit.lockAWT();
+        try {
+            return behaviour.isLightweight();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+
+    /**
+     * Checks whether or not this Component is shown.
+     * 
+     * @return true, if this Component is shown, false otherwise.
+     */
+    public boolean isShowing() {
+        //???AWT
+        /*
+        toolkit.lockAWT();
+        try {
+            return (isVisible() && isDisplayable() && (parent != null) && parent.isShowing());
+        } finally {
+            toolkit.unlockAWT();
+        }
+        */
+        return false;
+    }
+
+    /**
+     * Checks whether or not this Component is visible.
+     * 
+     * @return true, if the Component is visible, false otherwise.
+     */
+    public boolean isVisible() {
+        toolkit.lockAWT();
+        try {
+            return visible;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by processKeyEvent(KeyEvent) method.
+     * 
+     * @param evt the Event.
+     * @param key the key code.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by replaced by processKeyEvent(KeyEvent) method.
+     */
+    @Deprecated
+    public boolean keyDown(Event evt, int key) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by processKeyEvent(KeyEvent) method.
+     * 
+     * @param evt the Event.
+     * @param key the key code.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processKeyEvent(KeyEvent) method.
+     */
+    @Deprecated
+    public boolean keyUp(Event evt, int key) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: Replaced by doLayout() method.
+     * 
+     * @deprecated Replaced by doLayout() method.
+     */
+    @Deprecated
+    public void layout() {
+        toolkit.lockAWT();
+        try {
+            // Implemented in Container
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getComponentAt(int, int) method.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return The component.
+     * 
+     * @deprecated Replaced by getComponentAt(int, int) method.
+     */
+    @Deprecated
+    public Component locate(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            if (contains(x, y)) {
+                return this;
+            }
+            return null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by processFocusEvent(FocusEvent). 
+     * 
+     * @param evt the Event.
+     * @param what the Object.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processFocusEvent(FocusEvent).
+     */
+    @Deprecated
+    public boolean lostFocus(Event evt, Object what) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the MouseEvent.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseDown(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by getMinimumSize() method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by getMinimumSize() method.
+     */
+    @Deprecated
+    public boolean mouseDrag(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseEnter(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseExit(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @return true, if successful.
+     */
+    @Deprecated
+    public boolean mouseMove(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Replaced by processMouseEvent(MouseEvent) method.
+     * 
+     * @param evt the Event.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * 
+     * @return true, if successful.
+     * 
+     * @deprecated Replaced by processMouseEvent(MouseEvent) method.
+     */
+    @Deprecated
+    public boolean mouseUp(Event evt, int x, int y) {
+        // to be overridden: do nothing,
+        // just return false to propagate event up to the parent container
+        return false;
+    }
+
+    /**
+     * Deprecated: replaced by setLocation(int, int) method.
+     * 
+     * @param x the x coordinates.
+     * @param y the y coordinates.
+     * 
+     * @deprecated Replaced by setLocation(int, int) method.
+     */
+    @Deprecated
+    public void move(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            boundsMaskParam = NativeWindow.BOUNDS_NOSIZE;
+            setBounds(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    @Deprecated
+    public void nextFocus() {
+        toolkit.lockAWT();
+        try {
+            transferFocus(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Returns a string representation of the component's state.
+     * 
+     * @return the string representation of the component's state.
+     */
+    protected String paramString() {
+        /*
+         * The format is based on 1.5 release behavior which can be revealed by
+         * the following code:
+         * 
+         * Component c = new Component(){}; c.setVisible(false);
+         * System.out.println(c);
+         */
+        toolkit.lockAWT();
+        try {
+            return getName() + "," + getX() + "," + getY() + "," + getWidth() + "x" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                    + getHeight() + (!isVisible() ? ",hidden" : ""); //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    @Deprecated
+    @SuppressWarnings("deprecation")
+    public boolean postEvent(Event evt) {
+        boolean handled = handleEvent(evt);
+        if (handled) {
+            return true;
+        }
+        //???AWT
+        /*
+
+        // propagate non-handled events up to parent
+        Component par = parent;
+        // try to call postEvent only on components which
+        // override any of deprecated method handlers
+        // while (par != null && !par.deprecatedEventHandler) {
+        // par = par.parent;
+        // }
+        // translate event coordinates before posting it to parent
+        if (par != null) {
+            evt.translate(x, y);
+            par.postEvent(evt);
+        }
+        
+        */
+        return false;
+    }
+
+    /**
+     * Prepares an image for rendering on the Component. 
+     *  
+     * @param image the Image to be prepared.
+     * @param observer the ImageObserver object to be notified as soon as 
+     * the image is prepared.
+     * 
+     * @return true if the image has been fully prepared,
+     * false otherwise.
+     */
+    public boolean prepareImage(Image image, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.prepareImage(image, -1, -1, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prepares an image for rendering on the Component with the
+     * specified width, height, and ImageObserver. 
+     * 
+     * @param image the Image to be prepared.
+     * @param width the width of scaled image.
+     * @param height the height of scaled height.
+     * @param observer the ImageObserver object to be notified as soon as 
+     * the image is prepared.
+     * 
+     * @return true if the image is been fully prepared,
+     * false otherwise.
+     */
+    public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
+        toolkit.lockAWT();
+        try {
+            return toolkit.prepareImage(image, width, height, observer);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Makes this Component undisplayable.
+     */
+    public void removeNotify() {
+        toolkit.lockAWT();
+        try {
+            //???AWT
+            /*
+            if (dropTarget != null) {
+                dropTarget.removeNotify(peer);
+            }
+            */
+            prepare4HierarchyChange();
+            ///???AWT: moveFocus();
+            behaviour.removeNotify();
+            //???AWT: finishHierarchyChange(this, parent, 0);
+            removeNotifyInputContext();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Calls InputContext.removeNotify
+     */
+    private void removeNotifyInputContext() {
+        if (!inputMethodsEnabled) {
+            return;
+        }
+        InputContext ic = getInputContext();
+        if (ic != null) {
+            //???AWT: ic.removeNotify(this);
+        }
+    }
+
+    /**
+     * This method is called when some property of a component changes, making
+     * it unfocusable, e. g. hide(), removeNotify(), setEnabled(false),
+     * setFocusable(false) is called, and therefore automatic forward focus
+     * traversal is necessary
+     */
+    //???AWT
+    /*
+    void moveFocus() {
+        // don't use transferFocus(), but query focus traversal policy directly
+        // and if it returns null, transfer focus up cycle
+        // and find next focusable component there
+        KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+        Container root = kfm.getCurrentFocusCycleRoot();
+        Component nextComp = this;
+        boolean success = !isFocusOwner();
+        while (!success) {
+            if (root != nextComp.getFocusCycleRootAncestor()) {
+                // component was probably removed from container
+                // so focus will be lost in some time
+                return;
+            }
+            nextComp = root.getFocusTraversalPolicy().getComponentAfter(root, nextComp);
+            if (nextComp == this) {
+                nextComp = null; // avoid looping
+            }
+            if (nextComp != null) {
+                success = nextComp.requestFocusInWindow();
+            } else {
+                nextComp = root;
+                root = root.getFocusCycleRootAncestor();
+                // if no acceptable component is found at all - clear global
+                // focus owner
+                if (root == null) {
+                    if (nextComp instanceof Window) {
+                        Window wnd = (Window) nextComp;
+                        wnd.setFocusOwner(null);
+                        wnd.setRequestedFocus(null);
+                    }
+                    kfm.clearGlobalFocusOwner();
+                    return;
+                }
+            }
+        }
+    }
+    */
+
+    /**
+     * For Container there's a difference between moving focus when being made
+     * invisible or made unfocusable in some other way, because when container
+     * is made invisible, component still remains visible, i. e. its hide() or
+     * setVisible() is not called.
+     */
+    void moveFocusOnHide() {
+        //???AWT: moveFocus();
+    }
+
+    /**
+     * Removes the property change listener registered for this component.
+     * 
+     * @param listener the PropertyChangeListener.
+     */
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        getPropertyChangeSupport().removePropertyChangeListener(listener);
+    }
+
+    /**
+     * Removes the property change listener registered fot this component 
+     * for the specified propertyy.
+     * 
+     * @param propertyName the property name.
+     * @param listener the PropertyChangeListener.
+     */
+    public void removePropertyChangeListener(String propertyName,
+            PropertyChangeListener listener) {
+        getPropertyChangeSupport().removePropertyChangeListener(propertyName, listener);
+    }
+
+
+    /**
+     * Repaints the specified rectangle of this component within 
+     * tm milliseconds.
+     * 
+     * @param tm the time in milliseconds before updating.
+     * @param x the x coordinate of Rectangle.
+     * @param y the y coordinate of Rectangle.
+     * @param width the width of Rectangle.
+     * @param height the height of Rectangle.
+     */
+    public void repaint(long tm, int x, int y, int width, int height) {
+        //???AWT
+        /*
+        toolkit.lockAWT();
+        try {
+            if (width <= 0 || height <= 0 || (redrawManager == null) || !isShowing()) {
+                return;
+            }
+            if (behaviour instanceof LWBehavior) {
+                if (parent == null || !parent.visible || !parent.behaviour.isDisplayable()) {
+                    return;
+                }
+                if (repaintRegion == null) {
+                    repaintRegion = new MultiRectArea(new Rectangle(x, y, width, height));
+                }
+                repaintRegion.intersect(new Rectangle(0, 0, this.w, this.h));
+                repaintRegion.translate(this.x, this.y);
+                parent.repaintRegion = repaintRegion;
+                repaintRegion = null;
+                parent.repaint(tm, x + this.x, y + this.y, width, height);
+            } else {
+                if (repaintRegion != null) {
+                    redrawManager.addUpdateRegion(this, repaintRegion);
+                    repaintRegion = null;
+                } else {
+                    redrawManager.addUpdateRegion(this, new Rectangle(x, y, width, height));
+                }
+                toolkit.getSystemEventQueueCore().notifyEventMonitor(toolkit);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        */
+    }
+
+    /**
+     * Post event.
+     * 
+     * @param e the e
+     */
+    void postEvent(AWTEvent e) {
+        getToolkit().getSystemEventQueueImpl().postEvent(e);
+    }
+
+    /**
+     * Repaints the specified Rectangle of this Component.
+     * 
+     * @param x the x coordinate of Rectangle.
+     * @param y the y coordinate of Rectangle.
+     * @param width the width of Rectangle.
+     * @param height the height of Rectangle.
+     */
+    public void repaint(int x, int y, int width, int height) {
+        toolkit.lockAWT();
+        try {
+            repaint(0, x, y, width, height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Repaints this component.
+     */
+    public void repaint() {
+        toolkit.lockAWT();
+        try {
+            if (w > 0 && h > 0) {
+                repaint(0, 0, 0, w, h);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Repaints the component within tm milliseconds.
+     * 
+     * @param tm the time in milliseconds before updating.
+     */
+    public void repaint(long tm) {
+        toolkit.lockAWT();
+        try {
+            repaint(tm, 0, 0, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Requests that this Component get the input focus temporarily. 
+     * This component must be displayable, visible, and focusable.
+     * 
+     * @param temporary this parameter is true if the focus change 
+     * is temporary, when the window loses the focus.
+     * 
+     * @return true if the focus change request is succeeded,
+     * false otherwise.
+     */
+    protected boolean requestFocus(boolean temporary) {
+        toolkit.lockAWT();
+        try {
+            //???AWT: return requestFocusImpl(temporary, true, false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        //???AWT
+        return false;
+    }
+
+    /**
+     * Requests that this Component get the input focus. 
+     * This component must be displayable, visible, and focusable.
+     */
+    public void requestFocus() {
+        toolkit.lockAWT();
+        try {
+            requestFocus(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    protected boolean requestFocusInWindow(boolean temporary) {
+        toolkit.lockAWT();
+        try {
+            Window wnd = getWindowAncestor();
+            if ((wnd == null) || !wnd.isFocused()) {
+                return false;
+            }
+            return requestFocusImpl(temporary, false, false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    boolean requestFocusImpl(boolean temporary, boolean crossWindow, boolean rejectionRecovery) {
+        if (!rejectionRecovery && isFocusOwner()) {
+            return true;
+        }
+        Window wnd = getWindowAncestor();
+        Container par = getRealParent();
+        if ((par != null) && par.isRemoved) {
+            return false;
+        }
+        if (!isShowing() || !isFocusable() || !wnd.isFocusableWindow()) {
+            return false;
+        }
+        return KeyboardFocusManager.getCurrentKeyboardFocusManager().requestFocus(this,
+                temporary, crossWindow, true);
+    }
+
+    public boolean requestFocusInWindow() {
+        toolkit.lockAWT();
+        try {
+            return requestFocusInWindow(false);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Deprecated: replaced by setBounds(int, int, int, int) method.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param w the width. 
+     * @param h the height.
+     * 
+     * @deprecated Replaced by setBounds(int, int, int, int) method.
+     */
+    @Deprecated
+    public void reshape(int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            setBounds(x, y, w, h, boundsMaskParam, true);
+            boundsMaskParam = 0;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets rectangle for this Component to be the rectangle with the specified 
+     * x,y coordinates of the top-left corner and the width and height.
+     * 
+     * @param x the x coordinate of the rectangle's top-left corner.
+     * @param y the y coordinate of the rectangle's top-left corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle. 
+     */
+    public void setBounds(int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            reshape(x, y, w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets rectangle for this Component to be the rectangle with the specified 
+     * x,y coordinates of the top-left corner and the width and height
+     * and posts the appropriate events.
+     * 
+     * @param x the x coordinate of the rectangle's top-left corner.
+     * @param y the y coordinate of the rectangle's top-left corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle. 
+     * @param bMask the bitmask of bounds options
+     * @param updateBehavior the whether to update the behavoir's bounds as well
+     */
+    void setBounds(int x, int y, int w, int h, int bMask, boolean updateBehavior) {
+        int oldX = this.x;
+        int oldY = this.y;
+        int oldW = this.w;
+        int oldH = this.h;
+        setBoundsFields(x, y, w, h, bMask);
+        // Moved
+        if ((oldX != this.x) || (oldY != this.y)) {
+            //???AWT: invalidateRealParent();
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_MOVED));
+            spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_MOVED);
+        }
+        // Resized
+        if ((oldW != this.w) || (oldH != this.h)) {
+            invalidate();
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
+            spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_RESIZED);
+        }
+        if (updateBehavior) {
+            behaviour.setBounds(this.x, this.y, this.w, this.h, bMask);
+        }
+        notifyInputMethod(new Rectangle(x, y, w, h));
+    }
+
+    /**
+     * Calls InputContextImpl.notifyClientWindowChanged.
+     * 
+     * @param bounds the bounds
+     */
+    void notifyInputMethod(Rectangle bounds) {
+        // only Window actually notifies IM of bounds change
+    }
+
+    /**
+     * Sets the bounds fields.
+     * 
+     * @param x the x
+     * @param y the y
+     * @param w the w
+     * @param h the h
+     * @param bMask the b mask
+     */
+    private void setBoundsFields(int x, int y, int w, int h, int bMask) {
+        if ((bMask & NativeWindow.BOUNDS_NOSIZE) == 0) {
+            this.w = w;
+            this.h = h;
+        }
+        if ((bMask & NativeWindow.BOUNDS_NOMOVE) == 0) {
+            this.x = x;
+            this.y = y;
+        }
+    }
+
+    /**
+     * Gets the native insets.
+     * 
+     * @return the native insets
+     */
+    Insets getNativeInsets() {
+        return new Insets(0, 0, 0, 0);
+    }
+
+    /**
+     * Gets the insets.
+     * 
+     * @return the insets
+     */
+    Insets getInsets() {
+        return new Insets(0, 0, 0, 0);
+    }
+
+    /**
+     * Checks if is mouse exited expected.
+     * 
+     * @return true, if is mouse exited expected
+     */
+    boolean isMouseExitedExpected() {
+        return mouseExitedExpected;
+    }
+
+    /**
+     * Sets the mouse exited expected.
+     * 
+     * @param expected the new mouse exited expected
+     */
+    void setMouseExitedExpected(boolean expected) {
+        mouseExitedExpected = expected;
+    }
+
+    /**
+     * Sets the new bounding rectangle for this Component.
+     * 
+     * @param r the new bounding rectangle.
+     */
+    public void setBounds(Rectangle r) {
+        toolkit.lockAWT();
+        try {
+            setBounds(r.x, r.y, r.width, r.height);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the component orientation which affects the component's
+     * elements and text within this component. 
+     * 
+     * @param o the ComponentOrientation object.
+     */
+    public void setComponentOrientation(ComponentOrientation o) {
+        ComponentOrientation oldOrientation;
+        toolkit.lockAWT();
+        try {
+            oldOrientation = orientation;
+            orientation = o;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("componentOrientation", oldOrientation, orientation); //$NON-NLS-1$
+        invalidate();
+    }
+
+    /**
+     * Sets the specified cursor for this Component.
+     * 
+     * @param cursor the new Cursor.
+     */
+    public void setCursor(Cursor cursor) {
+        toolkit.lockAWT();
+        try {
+            this.cursor = cursor;
+            setCursor();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Set current cursor shape to Component's Cursor.
+     */
+    void setCursor() {
+        if (isDisplayable() && isShowing()) {
+            Rectangle absRect = new Rectangle(getLocationOnScreen(), getSize());
+            Point absPointerPos = toolkit.dispatcher.mouseDispatcher.getPointerPos();
+            //???AWT
+            /*
+            if (absRect.contains(absPointerPos)) {
+                // set Cursor only on top-level Windows(on X11)
+                Window topLevelWnd = getWindowAncestor();
+                if (topLevelWnd != null) {
+                    Point pointerPos = MouseDispatcher.convertPoint(null, absPointerPos,
+                            topLevelWnd);
+                    Component compUnderCursor = topLevelWnd.findComponentAt(pointerPos);
+                    // if (compUnderCursor == this ||
+                    // compUnderCursor.getCursorAncestor() == this) {
+                    NativeWindow wnd = topLevelWnd.getNativeWindow();
+                    if (compUnderCursor != null && wnd != null) {
+                        compUnderCursor.getRealCursor().getNativeCursor()
+                                .setCursor(wnd.getId());
+                    }
+                    // }
+                }
+            }
+            */
+        }
+    }
+
+    /**
+     * Gets the ancestor Cursor if Component is disabled (directly or via an
+     * ancestor) even if Cursor is explicitly set.
+     * 
+     * @param value the value
+     * 
+     * @return actual Cursor to be displayed
+     */
+    //???AWT
+    /*
+    Cursor getRealCursor() {
+        Component cursorAncestor = getCursorAncestor();
+        return cursorAncestor != null ? cursorAncestor.getCursor() : Cursor.getDefaultCursor();
+    }
+    */
+
+    /**
+     * Gets the ancestor(or component itself) whose cursor is set when pointer
+     * is inside component
+     * 
+     * @return actual Cursor to be displayed
+     */
+    //???AWT
+    /*
+    Component getCursorAncestor() {
+        Component comp;
+        for (comp = this; comp != null; comp = comp.getParent()) {
+            if (comp instanceof Window || comp.isCursorSet() && comp.isKeyEnabled()) {
+                return comp;
+            }
+        }
+        return null;
+    }
+
+    public void setDropTarget(DropTarget dt) {
+        toolkit.lockAWT();
+        try {
+            if (dropTarget == dt) {
+                return;
+            }
+            DropTarget oldDropTarget = dropTarget;
+            dropTarget = dt;
+            if (oldDropTarget != null) {
+                if (behaviour.isDisplayable()) {
+                    oldDropTarget.removeNotify(peer);
+                }
+                oldDropTarget.setComponent(null);
+            }
+            if (dt != null) {
+                dt.setComponent(this);
+                if (behaviour.isDisplayable()) {
+                    dt.addNotify(peer);
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+    
+    /**
+     * Sets this component to the "enabled" or "disabled" state depending
+     * on the specified boolean parameter.
+     * 
+     * @param value true if this component should be enabled; false
+     * if this component should be disabled.
+     */
+    public void setEnabled(boolean value) {
+        toolkit.lockAWT();
+        try {
+            enable(value);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the enabled impl.
+     * 
+     * @param value the new enabled impl
+     */
+    void setEnabledImpl(boolean value) {
+        if (enabled != value) {
+            enabled = value;
+            setCursor();
+            if (!enabled) {
+                moveFocusOnHide();
+            }
+            behaviour.setEnabled(value);
+        }
+    }
+
+    //???AWT
+    /*
+    private void fireAccessibleStateChange(AccessibleState state, boolean value) {
+        if (behaviour.isLightweight()) {
+            return;
+        }
+        AccessibleContext ac = getAccessibleContext();
+        if (ac != null) {
+            AccessibleState oldValue = null;
+            AccessibleState newValue = null;
+            if (value) {
+                newValue = state;
+            } else {
+                oldValue = state;
+            }
+            ac.firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY, oldValue,
+                    newValue);
+        }
+    }
+    */
+
+    //???AWT
+    /*
+    public void setFocusTraversalKeys(int id, Set<? extends AWTKeyStroke> keystrokes) {
+        Set<? extends AWTKeyStroke> oldTraversalKeys;
+        String propName = "FocusTraversalKeys"; //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            Integer kId = new Integer(id);
+            KeyboardFocusManager.checkTraversalKeysID(traversalKeys, kId);
+            Map<Integer, Set<? extends AWTKeyStroke>> keys = new HashMap<Integer, Set<? extends AWTKeyStroke>>();
+            for (int kid : traversalIDs) {
+                Integer key = new Integer(kid);
+                keys.put(key, getFocusTraversalKeys(kid));
+            }
+            KeyboardFocusManager.checkKeyStrokes(traversalIDs, keys, kId, keystrokes);
+            oldTraversalKeys = traversalKeys.get(new Integer(id));
+            // put a copy of keystrokes object into map:
+            Set<? extends AWTKeyStroke> newKeys = keystrokes;
+            if (keystrokes != null) {
+                newKeys = new HashSet<AWTKeyStroke>(keystrokes);
+            }
+            traversalKeys.put(kId, newKeys);
+            String direction = ""; //$NON-NLS-1$
+            switch (id) {
+                case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+                    direction = "forward"; //$NON-NLS-1$
+                    break;
+                case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+                    direction = "backward"; //$NON-NLS-1$
+                    break;
+                case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
+                    direction = "upCycle"; //$NON-NLS-1$
+                    break;
+                case KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS:
+                    direction = "downCycle"; //$NON-NLS-1$
+                    break;
+            }
+            propName = direction + propName;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange(propName, oldTraversalKeys, keystrokes);
+    }
+    */
+
+    /**
+     * Sets the focus traversal keys state for this component.
+     * 
+     * @param value true if the focus traversal keys state is enabled,
+     * false if the focus traversal keys state is disabled.
+     */
+    public void setFocusTraversalKeysEnabled(boolean value) {
+        boolean oldFocusTraversalKeysEnabled;
+        toolkit.lockAWT();
+        try {
+            oldFocusTraversalKeysEnabled = focusTraversalKeysEnabled;
+            focusTraversalKeysEnabled = value;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("focusTraversalKeysEnabled", oldFocusTraversalKeysEnabled, //$NON-NLS-1$
+                focusTraversalKeysEnabled);
+    }
+
+    //???AWT
+    /*
+    public void setFocusable(boolean focusable) {
+        boolean oldFocusable;
+        toolkit.lockAWT();
+        try {
+            calledSetFocusable = true;
+            oldFocusable = this.focusable;
+            this.focusable = focusable;
+            if (!focusable) {
+                moveFocus();
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("focusable", oldFocusable, focusable); //$NON-NLS-1$
+    }
+
+    public Font getFont() {
+        toolkit.lockAWT();
+        try {
+            return (font == null) && (parent != null) ? parent.getFont() : font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Sets the font for this Component.
+     * 
+     * @param f the new font of the Component.
+     */
+    public void setFont(Font f) {
+        Font oldFont;
+        toolkit.lockAWT();
+        try {
+            oldFont = font;
+            setFontImpl(f);
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("font", oldFont, font); //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the font impl.
+     * 
+     * @param f the new font impl
+     */
+    void setFontImpl(Font f) {
+        font = f;
+        invalidate();
+        if (isShowing()) {
+            repaint();
+        }
+    }
+
+
+    /**
+     * Invalidate the component if it inherits the font from the parent. This
+     * method is overridden in Container.
+     * 
+     * @return true if the component was invalidated, false otherwise
+     */
+    boolean propagateFont() {
+        if (font == null) {
+            invalidate();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sets the foreground color for this Component.
+     * 
+     * @param c the new foreground color.
+     */
+    public void setForeground(Color c) {
+        Color oldFgColor;
+        toolkit.lockAWT();
+        try {
+            oldFgColor = foreColor;
+            foreColor = c;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("foreground", oldFgColor, foreColor); //$NON-NLS-1$
+        repaint();
+    }
+
+    /**
+     * Sets the background color for the Component.
+     * 
+     * @param c the new background color for this component.
+     */
+    public void setBackground(Color c) {
+        Color oldBkColor;
+        toolkit.lockAWT();
+        try {
+            oldBkColor = backColor;
+            backColor = c;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("background", oldBkColor, backColor); //$NON-NLS-1$
+        repaint();
+    }
+
+    /**
+     * Sets the flag for whether paint messages received from the operating 
+     * system should be ignored or not. 
+     * 
+     * @param value true if paint messages received from the operating 
+     * system should be ignored, false otherwise.
+     */
+    public void setIgnoreRepaint(boolean value) {
+        toolkit.lockAWT();
+        try {
+            ignoreRepaint = value;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the locale of the component.
+     * 
+     * @param locale the new Locale.
+     */
+    public void setLocale(Locale locale) {
+        Locale oldLocale;
+        toolkit.lockAWT();
+        try {
+            oldLocale = this.locale;
+            this.locale = locale;
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("locale", oldLocale, locale); //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the location of the Component to the specified point.
+     * 
+     * @param p the new location of the Component
+     */
+    public void setLocation(Point p) {
+        toolkit.lockAWT();
+        try {
+            setLocation(p.x, p.y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the location of the Component to the specified x, y coordinates.  
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     */
+    public void setLocation(int x, int y) {
+        toolkit.lockAWT();
+        try {
+            move(x, y);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the visibility state of the component.
+     * 
+     * @param b true if the component is visible, false if the component
+     * is not shown.
+     */
+    public void setVisible(boolean b) {
+        // show() & hide() are not deprecated for Window,
+        // so have to call them from setVisible()
+        show(b);
+    }
+
+    /**
+     * Deprecated: replaced by setVisible(boolean) method.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void show() {
+        toolkit.lockAWT();
+        try {
+            if (visible) {
+                return;
+            }
+            prepare4HierarchyChange();
+            mapToDisplay(true);
+            validate();
+            visible = true;
+            behaviour.setVisible(true);
+            postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_SHOWN));
+            //???AWT: finishHierarchyChange(this, parent, 0);
+            notifyInputMethod(new Rectangle(x, y, w, h));
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by setVisible(boolean) method.
+     * 
+     * @param b the visibility's state.
+     * 
+     * @deprecated Replaced by setVisible(boolean) method.
+     */
+    @Deprecated
+    public void show(boolean b) {
+        if (b) {
+            show();
+        } else {
+            hide();
+        }
+    }
+
+    //???AWT
+    /*
+    void transferFocus(int dir) {
+        Container root = null;
+        if (this instanceof Container) {
+            Container cont = (Container) this;
+            if (cont.isFocusCycleRoot()) {
+                root = cont.getFocusTraversalRoot();
+            }
+        }
+        if (root == null) {
+            root = getFocusCycleRootAncestor();
+        }
+        // transfer focus up cycle if root is unreachable
+        Component comp = this;
+        while ((root != null)
+                && !(root.isFocusCycleRoot() && root.isShowing() && root.isEnabled() && root
+                        .isFocusable())) {
+            comp = root;
+            root = root.getFocusCycleRootAncestor();
+        }
+        if (root == null) {
+            return;
+        }
+        FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
+        Component nextComp = null;
+        switch (dir) {
+            case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
+                nextComp = policy.getComponentAfter(root, comp);
+                break;
+            case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
+                nextComp = policy.getComponentBefore(root, comp);
+                break;
+        }
+        if (nextComp != null) {
+            nextComp.requestFocus(false);
+        }
+    }
+    
+    public void transferFocus() {
+        toolkit.lockAWT();
+        try {
+            nextFocus();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    public void transferFocusBackward() {
+        toolkit.lockAWT();
+        try {
+            transferFocus(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    public void transferFocusUpCycle() {
+        toolkit.lockAWT();
+        try {
+            KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+            Container root = kfm.getCurrentFocusCycleRoot();
+            
+            if(root == null) {
+                return;
+            }
+            
+            boolean success = false;
+            Component nextComp = null;
+            Container newRoot = root;
+            do {
+                nextComp = newRoot instanceof Window ? newRoot.getFocusTraversalPolicy()
+                        .getDefaultComponent(newRoot) : newRoot;
+                newRoot = newRoot.getFocusCycleRootAncestor();
+                if (nextComp == null) {
+                    break;
+                }
+                success = nextComp.requestFocusInWindow();
+                if (newRoot == null) {
+                    break;
+                }
+                kfm.setGlobalCurrentFocusCycleRoot(newRoot);
+            } while (!success);
+            if (!success && root != newRoot) {
+                kfm.setGlobalCurrentFocusCycleRoot(root);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Validates that this component has a valid layout.
+     */
+    public void validate() {
+        toolkit.lockAWT();
+        try {
+            if (!behaviour.isDisplayable()) {
+                return;
+            }
+            validateImpl();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Validate impl.
+     */
+    void validateImpl() {
+        valid = true;
+    }
+
+    /**
+     * Gets the native window.
+     * 
+     * @return the native window
+     */
+    NativeWindow getNativeWindow() {
+        return behaviour.getNativeWindow();
+    }
+
+    /**
+     * Checks whether or not a maximum size is set for the Component.
+     * 
+     * @return true, if the maximum size is set for the Component,
+     * false otherwise.
+     */
+    public boolean isMaximumSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return maximumSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the minimum size is set for the component.
+     * 
+     * @return true, if the minimum size is set for the component,
+     * false otherwise.
+     */
+    public boolean isMinimumSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return minimumSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks whether or not the preferred size is set for the Component.
+     * 
+     * @return true, if the preferred size is set for the Component,
+     * false otherwise.
+     */
+    public boolean isPreferredSizeSet() {
+        toolkit.lockAWT();
+        try {
+            return preferredSize != null;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the maximum size of the Component.
+     * 
+     * @return the maximum size of the Component.
+     */
+    public Dimension getMaximumSize() {
+        toolkit.lockAWT();
+        try {
+            return isMaximumSizeSet() ? new Dimension(maximumSize) : new Dimension(
+                    Short.MAX_VALUE, Short.MAX_VALUE);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the minimum size of the Component.
+     * 
+     * @return the minimum size of the Component.
+     */
+    public Dimension getMinimumSize() {
+        toolkit.lockAWT();
+        try {
+            return minimumSize();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getMinimumSize() method.
+     * 
+     * @return the Dimension.
+     * 
+     * @deprecated Replaced by getMinimumSize() method.
+     */
+    @Deprecated
+    public Dimension minimumSize() {
+        toolkit.lockAWT();
+        try {
+            if (isMinimumSizeSet()) {
+                return (Dimension)minimumSize.clone();
+            }
+            Dimension defSize = getDefaultMinimumSize();
+            if (defSize != null) {
+                return (Dimension)defSize.clone();
+            }
+            return isDisplayable()? new Dimension(1, 1) : new Dimension(w, h);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the preferred size of the Component.
+     * 
+     * @return the preferred size of the Component.
+     */
+    public Dimension getPreferredSize() {
+        toolkit.lockAWT();
+        try {
+            return preferredSize();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Deprecated: replaced by getPreferredSize() method.
+     * 
+     * @return the Dimension.
+     * 
+     * @deprecated Replaced by getPreferredSize() method.
+     */
+    @Deprecated
+    public Dimension preferredSize() {
+        toolkit.lockAWT();
+        try {
+            if (isPreferredSizeSet()) {
+                return new Dimension(preferredSize);
+            }
+            Dimension defSize = getDefaultPreferredSize();
+            if (defSize != null) {
+                return new Dimension(defSize);
+            }
+            return new Dimension(getMinimumSize());
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the maximum size of the Component.
+     * 
+     * @param maximumSize the new maximum size of the Component.
+     */
+    public void setMaximumSize(Dimension maximumSize) {
+        Dimension oldMaximumSize;
+        toolkit.lockAWT();
+        try {
+            oldMaximumSize = this.maximumSize;
+            if (oldMaximumSize != null) {
+                oldMaximumSize = oldMaximumSize.getSize();
+            }
+            if (this.maximumSize == null) {
+                if (maximumSize != null) {
+                    this.maximumSize = new Dimension(maximumSize);
+                }
+            } else {
+                if (maximumSize != null) {
+                    this.maximumSize.setSize(maximumSize);
+                } else {
+                    this.maximumSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("maximumSize", oldMaximumSize, this.maximumSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the minimum size of the Component.
+     * 
+     * @param minimumSize the new minimum size of the Component.
+     */
+    public void setMinimumSize(Dimension minimumSize) {
+        Dimension oldMinimumSize;
+        toolkit.lockAWT();
+        try {
+            oldMinimumSize = this.minimumSize;
+            if (oldMinimumSize != null) {
+                oldMinimumSize = oldMinimumSize.getSize();
+            }
+            if (this.minimumSize == null) {
+                if (minimumSize != null) {
+                    this.minimumSize = new Dimension(minimumSize);
+                }
+            } else {
+                if (minimumSize != null) {
+                    this.minimumSize.setSize(minimumSize);
+                } else {
+                    this.minimumSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("minimumSize", oldMinimumSize, this.minimumSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the preferred size of the Component.
+     * 
+     * @param preferredSize the new preferred size of the Component.
+     */
+    public void setPreferredSize(Dimension preferredSize) {
+        Dimension oldPreferredSize;
+        toolkit.lockAWT();
+        try {
+            oldPreferredSize = this.preferredSize;
+            if (oldPreferredSize != null) {
+                oldPreferredSize = oldPreferredSize.getSize();
+            }
+            if (this.preferredSize == null) {
+                if (preferredSize != null) {
+                    this.preferredSize = new Dimension(preferredSize);
+                }
+            } else {
+                if (preferredSize != null) {
+                    this.preferredSize.setSize(preferredSize);
+                } else {
+                    this.preferredSize = null;
+                }
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+        firePropertyChange("preferredSize", oldPreferredSize, this.preferredSize); //$NON-NLS-1$
+        toolkit.lockAWT();
+        try {
+            //???AWT: invalidateRealParent();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    RedrawManager getRedrawManager() {
+        if (parent == null) {
+            return null;
+        }
+        return parent.getRedrawManager();
+    }
+    */
+
+    /**
+     * Checks if is focusability explicitly set.
+     * 
+     * @return true if component has a focusable peer
+     */
+    //???AWT
+    /*
+    boolean isPeerFocusable() {
+        // The recommendations for Windows and Unix are that
+        // Canvases, Labels, Panels, Scrollbars, ScrollPanes, Windows,
+        // and lightweight Components have non-focusable peers,
+        // and all other Components have focusable peers.
+        if (this instanceof Canvas || this instanceof Label || this instanceof Panel
+                || this instanceof Scrollbar || this instanceof ScrollPane
+                || this instanceof Window || isLightweight()) {
+            return false;
+        }
+        return true;
+    }
+    */
+
+    /**
+     * @return true if focusability was explicitly set via a call to
+     *         setFocusable() or via overriding isFocusable() or
+     *         isFocusTraversable()
+     */
+    boolean isFocusabilityExplicitlySet() {
+        return calledSetFocusable || overridenIsFocusable;
+    }
+
+    /**
+     * Paints the component and all of its subcomponents.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    public void paintAll(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Updates this Component.
+     * 
+     * @param g the Graphics to be used for updating.
+     */
+    public void update(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            if (!isLightweight() && !isPrepainter()) {
+                g.setColor(getBackground());
+                g.fillRect(0, 0, w, h);
+                g.setColor(getForeground());
+            }
+            paint(g);
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Paints this component.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    public void paint(Graphics g) {
+        toolkit.lockAWT();
+        try {
+            // Just to nothing
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Prepares the component to be painted.
+     * 
+     * @param g the Graphics to be used for painting.
+     */
+    void prepaint(Graphics g) {
+        // Just to nothing. For overriding.
+    }
+
+    /**
+     * Checks if is prepainter.
+     * 
+     * @return true, if is prepainter
+     */
+    boolean isPrepainter() {
+        return false;
+    }
+
+    /**
+     * Prepare4 hierarchy change.
+     */
+    void prepare4HierarchyChange() {
+        if (hierarchyChangingCounter++ == 0) {
+            wasShowing = isShowing();
+            wasDisplayable = isDisplayable();
+            prepareChildren4HierarchyChange();
+        }
+    }
+
+    /**
+     * Prepare children4 hierarchy change.
+     */
+    void prepareChildren4HierarchyChange() {
+        // To be inherited by Container
+    }
+
+    //???AWT
+    /*
+    void finishHierarchyChange(Component changed, Container changedParent, int ancestorFlags) {
+        if (--hierarchyChangingCounter == 0) {
+            int changeFlags = ancestorFlags;
+            if (wasShowing != isShowing()) {
+                changeFlags |= HierarchyEvent.SHOWING_CHANGED;
+            }
+            if (wasDisplayable != isDisplayable()) {
+                changeFlags |= HierarchyEvent.DISPLAYABILITY_CHANGED;
+            }
+            if (changeFlags > 0) {
+                postEvent(new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED, changed,
+                        changedParent, changeFlags));
+            }
+            finishChildrenHierarchyChange(changed, changedParent, ancestorFlags);
+        }
+    }
+
+
+    void finishChildrenHierarchyChange(Component changed, Container changedParent,
+            int ancestorFlags) {
+        // To be inherited by Container
+    }
+
+    void postHierarchyBoundsEvents(Component changed, int id) {
+        postEvent(new HierarchyEvent(this, id, changed, null, 0));
+    }
+    */
+    
+    /**
+     * Spread hierarchy bounds events.
+     * 
+     * @param changed the changed
+     * @param id the id
+     */
+    void spreadHierarchyBoundsEvents(Component changed, int id) {
+        // To be inherited by Container
+    }
+
+    /**
+     * Dispatches an event to this component.
+     * 
+     * @param e the Event.
+     */
+    public final void dispatchEvent(AWTEvent e) {
+        //???AWT
+        /*
+        if (e.isConsumed()) {
+            return;
+        }
+        if (e instanceof PaintEvent) {
+            toolkit.dispatchAWTEvent(e);
+            processPaintEvent((PaintEvent) e);
+            return;
+        }
+        KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+        if (!e.dispatchedByKFM && kfm.dispatchEvent(e)) {
+            return;
+        }
+        if (e instanceof KeyEvent) {
+            KeyEvent ke = (KeyEvent) e;
+            // consumes KeyEvent which represents a focus traversal key
+            if (getFocusTraversalKeysEnabled()) {
+                kfm.processKeyEvent(this, ke);
+                if (ke.isConsumed()) {
+                    return;
+                }
+            }
+        }
+        if (inputMethodsEnabled && dispatchToIM && e.isPosted && dispatchEventToIM(e)) {
+            return;
+        }
+        if (e.getID() == WindowEvent.WINDOW_ICONIFIED) {
+            notifyInputMethod(null);
+        }
+        AWTEvent.EventDescriptor descriptor = toolkit.eventTypeLookup.getEventDescriptor(e);
+        toolkit.dispatchAWTEvent(e);
+        if (descriptor != null) {
+            if (isEventEnabled(descriptor.eventMask)
+                    || (getListeners(descriptor.listenerType).length > 0)) {
+                processEvent(e);
+            }
+            // input events can be consumed by user listeners:
+            if (!e.isConsumed() && ((enabledAWTEvents & descriptor.eventMask) != 0)) {
+                postprocessEvent(e, descriptor.eventMask);
+            }
+        }
+        postDeprecatedEvent(e);
+        */
+    }
+
+    /**
+     * Post deprecated event.
+     * 
+     * @param e the e
+     */
+    private void postDeprecatedEvent(AWTEvent e) {
+        if (deprecatedEventHandler) {
+            Event evt = e.getEvent();
+            if (evt != null) {
+                postEvent(evt);
+            }
+        }
+    }
+
+    /**
+     * Postprocess event.
+     * 
+     * @param e the e
+     * @param eventMask the event mask
+     */
+    void postprocessEvent(AWTEvent e, long eventMask) {
+        toolkit.lockAWT();
+        try {
+            // call system listeners under AWT lock
+            if (eventMask == AWTEvent.FOCUS_EVENT_MASK) {
+                preprocessFocusEvent((FocusEvent) e);
+            } else if (eventMask == AWTEvent.KEY_EVENT_MASK) {
+                preprocessKeyEvent((KeyEvent) e);
+            } else if (eventMask == AWTEvent.MOUSE_EVENT_MASK) {
+                preprocessMouseEvent((MouseEvent) e);
+            } else if (eventMask == AWTEvent.MOUSE_MOTION_EVENT_MASK) {
+                preprocessMouseMotionEvent((MouseEvent) e);
+            } else if (eventMask == AWTEvent.COMPONENT_EVENT_MASK) {
+                preprocessComponentEvent((ComponentEvent) e);
+            } else if (eventMask == AWTEvent.MOUSE_WHEEL_EVENT_MASK) {
+                preprocessMouseWheelEvent((MouseWheelEvent) e);
+            } else if (eventMask == AWTEvent.INPUT_METHOD_EVENT_MASK) {
+                preprocessInputMethodEvent((InputMethodEvent) e);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Preprocess input method event.
+     * 
+     * @param e the e
+     */
+    private void preprocessInputMethodEvent(InputMethodEvent e) {
+        processInputMethodEventImpl(e, inputMethodListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse wheel event.
+     * 
+     * @param e the e
+     */
+    private void preprocessMouseWheelEvent(MouseWheelEvent e) {
+        processMouseWheelEventImpl(e, mouseWheelListeners.getSystemListeners());
+    }
+
+    /**
+     * Process mouse wheel event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processMouseWheelEventImpl(MouseWheelEvent e, Collection<MouseWheelListener> c) {
+        for (MouseWheelListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_WHEEL:
+                    listener.mouseWheelMoved(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Preprocess component event.
+     * 
+     * @param e the e
+     */
+    private void preprocessComponentEvent(ComponentEvent e) {
+        processComponentEventImpl(e, componentListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse motion event.
+     * 
+     * @param e the e
+     */
+    void preprocessMouseMotionEvent(MouseEvent e) {
+        processMouseMotionEventImpl(e, mouseMotionListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess mouse event.
+     * 
+     * @param e the e
+     */
+    void preprocessMouseEvent(MouseEvent e) {
+        processMouseEventImpl(e, mouseListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess key event.
+     * 
+     * @param e the e
+     */
+    void preprocessKeyEvent(KeyEvent e) {
+        processKeyEventImpl(e, keyListeners.getSystemListeners());
+    }
+
+    /**
+     * Preprocess focus event.
+     * 
+     * @param e the e
+     */
+    void preprocessFocusEvent(FocusEvent e) {
+        processFocusEventImpl(e, focusListeners.getSystemListeners());
+    }
+
+    /**
+     * Processes AWTEvent occurred on this component. 
+     * 
+     * @param e the AWTEvent.
+     */
+    protected void processEvent(AWTEvent e) {
+        long eventMask = toolkit.eventTypeLookup.getEventMask(e);
+        if (eventMask == AWTEvent.COMPONENT_EVENT_MASK) {
+            processComponentEvent((ComponentEvent) e);
+        } else if (eventMask == AWTEvent.FOCUS_EVENT_MASK) {
+            processFocusEvent((FocusEvent) e);
+        } else if (eventMask == AWTEvent.KEY_EVENT_MASK) {
+            processKeyEvent((KeyEvent) e);
+        } else if (eventMask == AWTEvent.MOUSE_EVENT_MASK) {
+            processMouseEvent((MouseEvent) e);
+        } else if (eventMask == AWTEvent.MOUSE_WHEEL_EVENT_MASK) {
+            processMouseWheelEvent((MouseWheelEvent) e);
+        } else if (eventMask == AWTEvent.MOUSE_MOTION_EVENT_MASK) {
+            processMouseMotionEvent((MouseEvent) e);
+        } else if (eventMask == AWTEvent.HIERARCHY_EVENT_MASK) {
+            processHierarchyEvent((HierarchyEvent) e);
+        } else if (eventMask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) {
+            processHierarchyBoundsEvent((HierarchyEvent) e);
+        } else if (eventMask == AWTEvent.INPUT_METHOD_EVENT_MASK) {
+            processInputMethodEvent((InputMethodEvent) e);
+        }
+    }
+
+    /**
+     * Gets an array of all listener's objects based on the specified
+     * listener type and registered to this Component.
+     * 
+     * @param listenerType the listener type.
+     * 
+     * @return an array of all listener's objects based on the specified
+     * listener type and registered to this Component. 
+     */
+    @SuppressWarnings("unchecked")
+    public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
+        if (ComponentListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getComponentListeners();
+        } else if (FocusListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getFocusListeners();
+        } else if (HierarchyBoundsListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getHierarchyBoundsListeners();
+        } else if (HierarchyListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getHierarchyListeners();
+        } else if (InputMethodListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getInputMethodListeners();
+        } else if (KeyListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getKeyListeners();
+        } else if (MouseWheelListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getMouseWheelListeners();
+        } else if (MouseMotionListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getMouseMotionListeners();
+        } else if (MouseListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getMouseListeners();
+        } else if (PropertyChangeListener.class.isAssignableFrom(listenerType)) {
+            return (T[]) getPropertyChangeListeners();
+        }
+        return (T[]) Array.newInstance(listenerType, 0);
+    }
+
+    /**
+     * Process paint event.
+     * 
+     * @param event the event
+     */
+    private void processPaintEvent(PaintEvent event) {
+        if (redrawManager == null) {
+            return;
+        }
+        Rectangle clipRect = event.getUpdateRect();
+        if ((clipRect.width <= 0) || (clipRect.height <= 0)) {
+            return;
+        }
+        Graphics g = getGraphics();
+        if (g == null) {
+            return;
+        }
+        initGraphics(g, event);
+        if (!getIgnoreRepaint()) {
+            if (event.getID() == PaintEvent.PAINT) {
+                paint(g);
+            } else {
+                update(g);
+            }
+        }
+        g.dispose();
+    }
+
+    /**
+     * Inits the graphics.
+     * 
+     * @param g the g
+     * @param e the e
+     */
+    void initGraphics(Graphics g, PaintEvent e) {
+        Rectangle clip = e.getUpdateRect();
+        if (clip instanceof ClipRegion) {
+            g.setClip(((ClipRegion) clip).getClip());
+        } else {
+            g.setClip(clip);
+        }
+        if (isPrepainter()) {
+            prepaint(g);
+        } else if (!isLightweight() && (e.getID() == PaintEvent.PAINT)) {
+            g.setColor(getBackground());
+            g.fillRect(0, 0, w, h);
+        }
+        g.setFont(getFont());
+        g.setColor(getForeground());
+    }
+
+    /**
+     * Enables the events with the specified event mask to be delivered to 
+     * this component.
+     * 
+     * @param eventsToEnable the events mask which specifies the types 
+     * of events to enable.
+     */
+    protected final void enableEvents(long eventsToEnable) {
+        toolkit.lockAWT();
+        try {
+            enabledEvents |= eventsToEnable;
+            deprecatedEventHandler = false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Enable awt events.
+     * 
+     * @param eventsToEnable the events to enable
+     */
+    private void enableAWTEvents(long eventsToEnable) {
+        enabledAWTEvents |= eventsToEnable;
+    }
+
+    /**
+     * Disables the events with types specified by the specified event mask 
+     * from being delivered to this component.
+     * 
+     * @param eventsToDisable the event mask specifying the event types. 
+     */
+    protected final void disableEvents(long eventsToDisable) {
+        toolkit.lockAWT();
+        try {
+            enabledEvents &= ~eventsToDisable;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /*
+     * For use in MouseDispatcher only. Really it checks not only mouse events.
+     */
+    /**
+     * Checks if is mouse event enabled.
+     * 
+     * @param eventMask the event mask
+     * 
+     * @return true, if is mouse event enabled
+     */
+    boolean isMouseEventEnabled(long eventMask) {
+        return (isEventEnabled(eventMask) || (enabledAWTEvents & eventMask) != 0);
+    }
+
+    /**
+     * Checks if is event enabled.
+     * 
+     * @param eventMask the event mask
+     * 
+     * @return true, if is event enabled
+     */
+    boolean isEventEnabled(long eventMask) {
+        return ((enabledEvents & eventMask) != 0);
+    }
+
+    /**
+     * Enables or disables input method support for this component. 
+     * 
+     * @param enable true to enable input method support, false to disable it. 
+     */
+    public void enableInputMethods(boolean enable) {
+        toolkit.lockAWT();
+        try {
+            if (!enable) {
+                removeNotifyInputContext();
+            }
+            inputMethodsEnabled = enable;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets an array of all component's listeners registered for this
+     * component.
+     * 
+     * @return an array of all component's listeners registered for this
+     * component.
+     */
+    public ComponentListener[] getComponentListeners() {
+        return componentListeners.getUserListeners(new ComponentListener[0]);
+    }
+
+    /**
+     * Adds the specified component listener to the Component for receiving
+     * component's event.
+     * 
+     * @param l the ComponentListener.
+     */
+    public void addComponentListener(ComponentListener l) {
+        componentListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the component listener registered for this Component.
+     * 
+     * @param l the ComponentListener.
+     */
+    public void removeComponentListener(ComponentListener l) {
+        componentListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a component event that has occurred on this component 
+     * by dispatching them to any registered ComponentListener objects.
+     * 
+     * @param e the ComponentEvent.
+     */
+    protected void processComponentEvent(ComponentEvent e) {
+        processComponentEventImpl(e, componentListeners.getUserListeners());
+    }
+
+    /**
+     * Process component event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processComponentEventImpl(ComponentEvent e, Collection<ComponentListener> c) {
+        for (ComponentListener listener : c) {
+            switch (e.getID()) {
+                case ComponentEvent.COMPONENT_HIDDEN:
+                    listener.componentHidden(e);
+                    break;
+                case ComponentEvent.COMPONENT_MOVED:
+                    listener.componentMoved(e);
+                    break;
+                case ComponentEvent.COMPONENT_RESIZED:
+                    listener.componentResized(e);
+                    break;
+                case ComponentEvent.COMPONENT_SHOWN:
+                    listener.componentShown(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of focus listeners registered for this Component.
+     * 
+     * @return the array of focus listeners registered for this Component.
+     */
+    public FocusListener[] getFocusListeners() {
+        return focusListeners.getUserListeners(new FocusListener[0]);
+    }
+
+    /**
+     * Adds the specified focus listener to the Component for receiving
+     * focus events.
+     * 
+     * @param l the FocusListener.
+     */
+    public void addFocusListener(FocusListener l) {
+        focusListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt focus listener.
+     * 
+     * @param l the l
+     */
+    void addAWTFocusListener(FocusListener l) {
+        enableAWTEvents(AWTEvent.FOCUS_EVENT_MASK);
+        focusListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the focus listener registered for this Component.
+     * 
+     * @param l the FocusListener.
+     */
+    public void removeFocusListener(FocusListener l) {
+        focusListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a FocusEvent that has occurred on this component
+     * by dispatching it to the registered listeners.
+     *  
+     * @param e the FocusEvent.
+     */
+    protected void processFocusEvent(FocusEvent e) {
+        processFocusEventImpl(e, focusListeners.getUserListeners());
+    }
+
+    /**
+     * Process focus event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processFocusEventImpl(FocusEvent e, Collection<FocusListener> c) {
+        for (FocusListener listener : c) {
+            switch (e.getID()) {
+                case FocusEvent.FOCUS_GAINED:
+                    listener.focusGained(e);
+                    break;
+                case FocusEvent.FOCUS_LOST:
+                    listener.focusLost(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of registered HierarchyListeners for
+     * this Component.
+     * 
+     * @return an array of registered HierarchyListeners for
+     * this Component.
+     */
+    public HierarchyListener[] getHierarchyListeners() {
+        return hierarchyListeners.getUserListeners(new HierarchyListener[0]);
+    }
+
+    /**
+     * Adds the specified hierarchy listener.
+     * 
+     * @param l the HierarchyListener.
+     */
+    public void addHierarchyListener(HierarchyListener l) {
+        hierarchyListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the hierarchy listener registered for this component.
+     * 
+     * @param l the HierarchyListener.
+     */
+    public void removeHierarchyListener(HierarchyListener l) {
+        hierarchyListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a hierarchy event that has occurred on this component
+     * by dispatching it to the registered listeners. 
+     * 
+     * @param e the HierarchyEvent.
+     */
+    protected void processHierarchyEvent(HierarchyEvent e) {
+        for (HierarchyListener listener : hierarchyListeners.getUserListeners()) {
+            switch (e.getID()) {
+                case HierarchyEvent.HIERARCHY_CHANGED:
+                    listener.hierarchyChanged(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of HierarchyBoundsListener objects registered
+     * to this Component.
+     * 
+     * @return an array of HierarchyBoundsListener objects.
+     */
+    public HierarchyBoundsListener[] getHierarchyBoundsListeners() {
+        return hierarchyBoundsListeners.getUserListeners(new HierarchyBoundsListener[0]);
+    }
+
+    /**
+     * Adds the specified hierarchy bounds listener.
+     * 
+     * @param l the HierarchyBoundsListener.
+     */
+    public void addHierarchyBoundsListener(HierarchyBoundsListener l) {
+        hierarchyBoundsListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the hierarchy bounds listener registered for this Component.
+     * 
+     * @param l the HierarchyBoundsListener.
+     */
+    public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {
+        hierarchyBoundsListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a hierarchy bounds event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     *  
+     * @param e the HierarchyBoundsEvent.
+     */
+    protected void processHierarchyBoundsEvent(HierarchyEvent e) {
+        for (HierarchyBoundsListener listener : hierarchyBoundsListeners.getUserListeners()) {
+            switch (e.getID()) {
+                case HierarchyEvent.ANCESTOR_MOVED:
+                    listener.ancestorMoved(e);
+                    break;
+                case HierarchyEvent.ANCESTOR_RESIZED:
+                    listener.ancestorResized(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the key listeners registered to the Component.
+     * 
+     * @return an array of the key listeners registered to the Component.
+     */
+    public KeyListener[] getKeyListeners() {
+        return keyListeners.getUserListeners(new KeyListener[0]);
+    }
+
+    /**
+     * Adds the specified key listener.
+     * 
+     * @param l the KeyListener.
+     */
+    public void addKeyListener(KeyListener l) {
+        keyListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt key listener.
+     * 
+     * @param l the l
+     */
+    void addAWTKeyListener(KeyListener l) {
+        enableAWTEvents(AWTEvent.KEY_EVENT_MASK);
+        keyListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the key listener registered for this Component.
+     * 
+     * @param l the KeyListener.
+     */
+    public void removeKeyListener(KeyListener l) {
+        keyListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a key event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the KeyEvent.
+     */
+    protected void processKeyEvent(KeyEvent e) {
+        processKeyEventImpl(e, keyListeners.getUserListeners());
+    }
+
+    /**
+     * Process key event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processKeyEventImpl(KeyEvent e, Collection<KeyListener> c) {
+        for (KeyListener listener : c) {
+            switch (e.getID()) {
+                case KeyEvent.KEY_PRESSED:
+                    listener.keyPressed(e);
+                    break;
+                case KeyEvent.KEY_RELEASED:
+                    listener.keyReleased(e);
+                    break;
+                case KeyEvent.KEY_TYPED:
+                    listener.keyTyped(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the mouse listeners registered to the Component.
+     * 
+     * @return an array of the mouse listeners registered to the Component.
+     */
+    public MouseListener[] getMouseListeners() {
+        return mouseListeners.getUserListeners(new MouseListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse listener.
+     * 
+     * @param l the MouseListener.
+     */
+    public void addMouseListener(MouseListener l) {
+        mouseListeners.addUserListener(l);
+    }
+
+    /**
+     * Adds the awt mouse listener.
+     * 
+     * @param l the l
+     */
+    void addAWTMouseListener(MouseListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_EVENT_MASK);
+        mouseListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt mouse motion listener.
+     * 
+     * @param l the l
+     */
+    void addAWTMouseMotionListener(MouseMotionListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
+        mouseMotionListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt component listener.
+     * 
+     * @param l the l
+     */
+    void addAWTComponentListener(ComponentListener l) {
+        enableAWTEvents(AWTEvent.COMPONENT_EVENT_MASK);
+        componentListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt input method listener.
+     * 
+     * @param l the l
+     */
+    void addAWTInputMethodListener(InputMethodListener l) {
+        enableAWTEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
+        inputMethodListeners.addSystemListener(l);
+    }
+
+    /**
+     * Adds the awt mouse wheel listener.
+     * 
+     * @param l the l
+     */
+    void addAWTMouseWheelListener(MouseWheelListener l) {
+        enableAWTEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
+        mouseWheelListeners.addSystemListener(l);
+    }
+
+    /**
+     * Removes the mouse listener registered for this Component.
+     * 
+     * @param l the MouseListener.
+     */
+    public void removeMouseListener(MouseListener l) {
+        mouseListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the MouseEvent.
+     */
+    protected void processMouseEvent(MouseEvent e) {
+        processMouseEventImpl(e, mouseListeners.getUserListeners());
+    }
+
+    /**
+     * Process mouse event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processMouseEventImpl(MouseEvent e, Collection<MouseListener> c) {
+        for (MouseListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_CLICKED:
+                    listener.mouseClicked(e);
+                    break;
+                case MouseEvent.MOUSE_ENTERED:
+                    listener.mouseEntered(e);
+                    break;
+                case MouseEvent.MOUSE_EXITED:
+                    listener.mouseExited(e);
+                    break;
+                case MouseEvent.MOUSE_PRESSED:
+                    listener.mousePressed(e);
+                    break;
+                case MouseEvent.MOUSE_RELEASED:
+                    listener.mouseReleased(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Process mouse motion event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processMouseMotionEventImpl(MouseEvent e, Collection<MouseMotionListener> c) {
+        for (MouseMotionListener listener : c) {
+            switch (e.getID()) {
+                case MouseEvent.MOUSE_DRAGGED:
+                    listener.mouseDragged(e);
+                    break;
+                case MouseEvent.MOUSE_MOVED:
+                    listener.mouseMoved(e);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Gets an array of the mouse motion listeners registered to
+     * the Component.
+     * 
+     * @return an array of the MouseMotionListeners registered to
+     * the Component.
+     */
+    public MouseMotionListener[] getMouseMotionListeners() {
+        return mouseMotionListeners.getUserListeners(new MouseMotionListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse motion listener.
+     * 
+     * @param l the MouseMotionListener.
+     */
+    public void addMouseMotionListener(MouseMotionListener l) {
+        mouseMotionListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the mouse motion listener registered for this component.
+     * 
+     * @param l the MouseMotionListener.
+     */
+    public void removeMouseMotionListener(MouseMotionListener l) {
+        mouseMotionListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse motion event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the MouseEvent.
+     */
+    protected void processMouseMotionEvent(MouseEvent e) {
+        processMouseMotionEventImpl(e, mouseMotionListeners.getUserListeners());
+    }
+
+    /**
+     * Gets an array of the mouse wheel listeners registered to
+     * the Component.
+     * 
+     * @return an array of the MouseWheelListeners registered to
+     * the Component.
+     */
+    public MouseWheelListener[] getMouseWheelListeners() {
+        return mouseWheelListeners.getUserListeners(new MouseWheelListener[0]);
+    }
+
+    /**
+     * Adds the specified mouse wheel listener.
+     * 
+     * @param l the MouseWheelListener.
+     */
+    public void addMouseWheelListener(MouseWheelListener l) {
+        mouseWheelListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the mouse wheel listener registered for this component.
+     * 
+     * @param l the MouseWheelListener.
+     */
+    public void removeMouseWheelListener(MouseWheelListener l) {
+        mouseWheelListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes a mouse wheel event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the MouseWheelEvent.
+     */
+    protected void processMouseWheelEvent(MouseWheelEvent e) {
+        processMouseWheelEventImpl(e, mouseWheelListeners.getUserListeners());
+    }
+
+    /**
+     * Gets an array of the InputMethodListener listeners 
+     * registered to the Component.
+     * 
+     * @return an array of the InputMethodListener listeners 
+     * registered to the Component.
+     */
+    public InputMethodListener[] getInputMethodListeners() {
+        return inputMethodListeners.getUserListeners(new InputMethodListener[0]);
+    }
+
+    /**
+     * Adds the specified input method listener.
+     * 
+     * @param l the InputMethodListener.
+     */
+    public void addInputMethodListener(InputMethodListener l) {
+        inputMethodListeners.addUserListener(l);
+    }
+
+    /**
+     * Removes the input method listener registered for this component.
+     * 
+     * @param l the InputMethodListener.
+     */
+    public void removeInputMethodListener(InputMethodListener l) {
+        inputMethodListeners.removeUserListener(l);
+    }
+
+    /**
+     * Processes an input method event that has occurred on this component
+     * by dispatching it to the registered listeners.
+     * 
+     * @param e the InputMethodEvent.
+     */
+    protected void processInputMethodEvent(InputMethodEvent e) {
+        processInputMethodEventImpl(e, inputMethodListeners.getUserListeners());
+    }
+
+    /**
+     * Process input method event impl.
+     * 
+     * @param e the e
+     * @param c the c
+     */
+    private void processInputMethodEventImpl(InputMethodEvent e,
+            Collection<InputMethodListener> c) {
+        for (InputMethodListener listener : c) {
+            switch (e.getID()) {
+                case InputMethodEvent.CARET_POSITION_CHANGED:
+                    listener.caretPositionChanged(e);
+                    break;
+                case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
+                    listener.inputMethodTextChanged(e);
+                    break;
+            }
+        }
+    }
+
+    //???AWT
+    /*
+    public Point getMousePosition() throws HeadlessException {
+        Point absPointerPos = MouseInfo.getPointerInfo().getLocation();
+        Window winUnderPtr = toolkit.dispatcher.mouseDispatcher.findWindowAt(absPointerPos);
+        Point pointerPos = MouseDispatcher.convertPoint(null, absPointerPos, winUnderPtr);
+        boolean isUnderPointer = false;
+        if (winUnderPtr == null) {
+            return null;
+        }
+        isUnderPointer = winUnderPtr.isComponentAt(this, pointerPos);
+        if (isUnderPointer) {
+            return MouseDispatcher.convertPoint(null, absPointerPos, this);
+        }
+        return null;
+    }
+    */
+
+    /**
+     * Set native caret at the given position <br>
+     * Note: this method takes AWT lock inside because it walks through the
+     * component hierarchy.
+     * 
+     * @param x the x
+     * @param y the y
+     */
+    void setCaretPos(final int x, final int y) {
+        Runnable r = new Runnable() {
+            public void run() {
+                toolkit.lockAWT();
+                try {
+                    setCaretPosImpl(x, y);
+                } finally {
+                    toolkit.unlockAWT();
+                }
+            }
+        };
+        if (Thread.currentThread() instanceof EventDispatchThread) {
+            r.run();
+        } else {
+            toolkit.getSystemEventQueueImpl().postEvent(new InvocationEvent(this, r));
+        }
+    }
+
+    /**
+     * This method should be called only at event dispatch thread.
+     * 
+     * @param x the x
+     * @param y the y
+     */
+    void setCaretPosImpl(int x, int y) {
+        Component c = this;
+        while ((c != null) && c.behaviour.isLightweight()) {
+            x += c.x;
+            y += c.y;
+            //???AWT: c = c.getParent();
+        }
+        if (c == null) {
+            return;
+        }
+        //???AWT
+        /*
+        if (c instanceof Window) {
+            Insets insets = c.getNativeInsets();
+            x -= insets.left;
+            y -= insets.top;
+        }
+        toolkit.getWindowFactory().setCaretPosition(x, y);
+        */
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Gets the default minimum size.
+     * 
+     * @return the default minimum size
+     */
+    Dimension getDefaultMinimumSize() {
+        return null;
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Gets the default preferred size.
+     * 
+     * @return the default preferred size
+     */
+    Dimension getDefaultPreferredSize() {
+        return null;
+    }
+
+    // to be overridden in standard components such as Button and List
+    /**
+     * Reset default size.
+     */
+    void resetDefaultSize() {
+    }
+
+    //???AWT
+    /*
+    ComponentBehavior createBehavior() {
+        return new LWBehavior(this);
+    }
+    */
+
+    /**
+     * Gets the default background.
+     * 
+     * @return the default background
+     */
+    Color getDefaultBackground() {
+        //???AWT: return getWindowAncestor().getDefaultBackground();
+        return getBackground();
+    }
+
+    /**
+     * Gets the default foreground.
+     * 
+     * @return the default foreground
+     */
+    Color getDefaultForeground() {
+        //???AWT return getWindowAncestor().getDefaultForeground();
+        return getForeground();
+    }
+
+    /**
+     * Called when native resource for this component is created (for
+     * heavyweights only).
+     * 
+     * @param win the win
+     */
+    void nativeWindowCreated(NativeWindow win) {
+        // to be overridden
+    }
+
+    /**
+     * Determine the component's area hidden behind the windows that have higher
+     * Z-order, including windows of other applications.
+     * 
+     * @param image the image
+     * @param destLocation the dest location
+     * @param destSize the dest size
+     * @param source the source
+     * 
+     * @return the calculated region, or null if it cannot be determined
+     */
+    //???AWT
+    /*
+    MultiRectArea getObscuredRegion(Rectangle part) {
+        if (!visible || parent == null || !parent.visible) {
+            return null;
+        }
+        Rectangle r = new Rectangle(0, 0, w, h);
+        if (part != null) {
+            r = r.intersection(part);
+        }
+        if (r.isEmpty()) {
+            return null;
+        }
+        r.translate(x, y);
+        MultiRectArea ret = parent.getObscuredRegion(r);
+        if (ret != null) {
+            parent.addObscuredRegions(ret, this);
+            ret.translate(-x, -y);
+            ret.intersect(new Rectangle(0, 0, w, h));
+        }
+        return ret;
+    }
+    */
+
+    //???AWT
+    /*
+    private void readObject(ObjectInputStream stream) throws IOException,
+            ClassNotFoundException {
+        stream.defaultReadObject();
+        FieldsAccessor accessor = new FieldsAccessor(Component.class, this);
+        accessor.set("toolkit", Toolkit.getDefaultToolkit()); //$NON-NLS-1$
+        accessor.set("behaviour", createBehavior()); //$NON-NLS-1$
+        accessor.set("componentLock", new Object()); // $NON-LOCK-1$ //$NON-NLS-1$
+    }
+    */
+
+    final void onDrawImage(Image image, Point destLocation, Dimension destSize, Rectangle source) {
+        ImageParameters imageParams;
+        if (updatedImages == null) {
+            updatedImages = new HashMap<Image, ImageParameters>();
+        }
+        imageParams = updatedImages.get(image);
+        if (imageParams == null) {
+            imageParams = new ImageParameters();
+            updatedImages.put(image, imageParams);
+        }
+        imageParams.addDrawing(destLocation, destSize, source);
+    }
+
+    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
+        toolkit.lockAWT();
+        try {
+            boolean done = false;
+            if ((infoflags & (ALLBITS | FRAMEBITS)) != 0) {
+                done = true;
+            } else if ((infoflags & SOMEBITS) != 0 && incrementalImageUpdate) {
+                done = true;
+            }
+            if (done) {
+                repaint();
+            }
+            return (infoflags & (ABORT | ALLBITS)) == 0;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    private void invalidateRealParent() {
+        Container realParent = getRealParent();
+        if ((realParent != null) && realParent.isValid()) {
+            realParent.invalidate();
+        }
+    }
+    */
+
+    /**
+     * The Class ImageParameters.
+     */
+    private class ImageParameters {
+        
+        /** The drawing params. */
+        private final LinkedList<DrawingParameters> drawingParams = new LinkedList<DrawingParameters>();
+
+        /** The size. */
+        Dimension size = new Dimension(Component.this.w, Component.this.h);
+
+        /**
+         * Adds the drawing.
+         * 
+         * @param destLocation the dest location
+         * @param destSize the dest size
+         * @param source the source
+         */
+        void addDrawing(Point destLocation, Dimension destSize, Rectangle source) {
+            drawingParams.add(new DrawingParameters(destLocation, destSize, source));
+        }
+
+        /**
+         * Drawing parameters iterator.
+         * 
+         * @return the iterator< drawing parameters>
+         */
+        Iterator<DrawingParameters> drawingParametersIterator() {
+            return drawingParams.iterator();
+        }
+
+        /**
+         * The Class DrawingParameters.
+         */
+        class DrawingParameters {
+            
+            /** The dest location. */
+            Point destLocation;
+
+            /** The dest size. */
+            Dimension destSize;
+
+            /** The source. */
+            Rectangle source;
+
+            /**
+             * Instantiates a new drawing parameters.
+             * 
+             * @param destLocation the dest location
+             * @param destSize the dest size
+             * @param source the source
+             */
+            DrawingParameters(Point destLocation, Dimension destSize, Rectangle source) {
+                this.destLocation = new Point(destLocation);
+                if (destSize != null) {
+                    this.destSize = new Dimension(destSize);
+                } else {
+                    this.destSize = null;
+                }
+                if (source != null) {
+                    this.source = new Rectangle(source);
+                } else {
+                    this.source = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * TextComponent support.
+     * 
+     * @param e the e
+     * 
+     * @return true, if dispatch event to im
+     */
+    //???AWT
+    /*
+    private TextKit textKit = null;
+
+    TextKit getTextKit() {
+        return textKit;
+    }
+
+    void setTextKit(TextKit kit) {
+        textKit = kit;
+    }
+    */
+
+    /**
+     * TextField support
+     */
+    //???AWT
+    /*
+    private TextFieldKit textFieldKit = null;
+
+    TextFieldKit getTextFieldKit() {
+        return textFieldKit;
+    }
+
+    void setTextFieldKit(TextFieldKit kit) {
+        textFieldKit = kit;
+    }
+    */
+
+    /**
+     * Dispatches input & focus events to input method
+     * context.
+     * @param e event to pass to InputContext.dispatchEvent()
+     * @return true if event was consumed by IM, false otherwise
+     */
+    private boolean dispatchEventToIM(AWTEvent e) {
+        InputContext ic = getInputContext();
+        if (ic == null) {
+            return false;
+        }
+        int id = e.getID();
+        boolean isInputEvent = ((id >= KeyEvent.KEY_FIRST) && (id <= KeyEvent.KEY_LAST))
+                || ((id >= MouseEvent.MOUSE_FIRST) && (id <= MouseEvent.MOUSE_LAST));
+        if (((id >= FocusEvent.FOCUS_FIRST) && (id <= FocusEvent.FOCUS_LAST)) || isInputEvent) {
+            ic.dispatchEvent(e);
+        }
+        return e.isConsumed();
+    }
+}
diff --git a/awt/java/awt/ComponentBehavior.java b/awt/java/awt/ComponentBehavior.java
new file mode 100644
index 0000000..89c9999
--- /dev/null
+++ b/awt/java/awt/ComponentBehavior.java
@@ -0,0 +1,56 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+/**
+ * The interface of the helper object that encapsulates the difference
+ * between lightweight and heavyweight components. 
+ */
+interface ComponentBehavior {
+
+    void addNotify();
+
+    void setBounds(int x, int y, int w, int h, int bMask);
+
+    void setVisible(boolean b);
+
+    Graphics getGraphics(int translationX, int translationY, int width, int height);
+
+    NativeWindow getNativeWindow();
+
+    boolean isLightweight();
+
+    void onMove(int x, int y);
+
+    boolean isOpaque();
+
+    boolean isDisplayable();
+
+    void setEnabled(boolean value);
+
+    void removeNotify();
+
+    void setZOrder(int newIndex, int oldIndex);
+
+    boolean setFocus(boolean focus, Component opposite);
+}
diff --git a/awt/java/awt/ComponentOrientation.java b/awt/java/awt/ComponentOrientation.java
new file mode 100644
index 0000000..ddb118d
--- /dev/null
+++ b/awt/java/awt/ComponentOrientation.java
@@ -0,0 +1,140 @@
+/*
+ *  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 Michael Danilov, Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * The ComponentOrientation class specifies the language-sensitive orientation 
+ * of component's elements or text. It is used to reflect the differences in this 
+ * ordering between different writting systems. The ComponentOrientation class 
+ * indicates the orientation of the elements/text in the horizontal direction
+ * ("left to right" or "right to left") and in the vertical direction
+ * ("top to bottom" or "bottom to top").
+ */
+public final class ComponentOrientation implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4113291392143563828L;
+
+    /** 
+     * The Constant LEFT_TO_RIGHT indicates that items run left to right.
+     */
+    public static final ComponentOrientation LEFT_TO_RIGHT = new ComponentOrientation(true, true);
+
+    /** 
+     * The Constant RIGHT_TO_LEFT indicates that items run right to left.
+     */
+    public static final ComponentOrientation RIGHT_TO_LEFT = new ComponentOrientation(true, false);
+
+    /** The Constant UNKNOWN indicates that a component's orientation is not set. */
+    public static final ComponentOrientation UNKNOWN = new ComponentOrientation(true, true);
+
+    /** The Constant rlLangs. */
+    private static final Set<String> rlLangs = new HashSet<String>(); //RIGHT_TO_LEFT languages
+
+    /** The horizontal. */
+    private final boolean horizontal;
+
+    /** The left2right. */
+    private final boolean left2right;
+
+    static {
+        rlLangs.add("ar"); //$NON-NLS-1$
+        rlLangs.add("fa"); //$NON-NLS-1$
+        rlLangs.add("iw"); //$NON-NLS-1$
+        rlLangs.add("ur"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the orientation for the given ResourceBundle's localization.
+     * 
+     * @param bdl the ResourceBundle.
+     * 
+     * @return the ComponentOrientation.
+     * 
+     * @deprecated Use getOrientation(java.util.Locale) method.
+     */
+    @Deprecated
+    public static ComponentOrientation getOrientation(ResourceBundle bdl) {
+        Object obj = null;
+        try {
+            obj = bdl.getObject("Orientation"); //$NON-NLS-1$
+        }
+        catch (MissingResourceException mre) {
+            obj = null;
+        }
+        if (obj instanceof ComponentOrientation) {
+            return (ComponentOrientation) obj;
+        }
+        Locale locale = bdl.getLocale();
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        return getOrientation(locale);
+    }
+
+    /**
+     * Gets the orientation for the specified locale.
+     * 
+     * @param locale the specified Locale.
+     * 
+     * @return the ComponentOrientation.
+     */
+    public static ComponentOrientation getOrientation(Locale locale) {
+        String lang = locale.getLanguage();
+        return rlLangs.contains(lang) ? RIGHT_TO_LEFT : LEFT_TO_RIGHT;
+    }
+
+    /**
+     * Instantiates a new component orientation.
+     * 
+     * @param hor whether the items should be arranged horizontally
+     * @param l2r whether this orientation specifies a left-to-right flow
+     */
+    private ComponentOrientation(boolean hor, boolean l2r) {
+        horizontal = hor;
+        left2right = l2r;
+    }
+
+    /**
+     * Returns true if the text of the of writing systems arranged
+     * horizontally.
+     * 
+     * @return true, if the text is written horizontally, false 
+     * for a vertical arrangement. 
+     */
+    public boolean isHorizontal() {
+        return horizontal;
+    }
+
+    /**
+     * Returns true if the text is arranged from left to right.
+     * 
+     * @return true, for writing systems written from left to right; 
+     * false for right-to-left.
+     */
+    public boolean isLeftToRight() {
+        return left2right;
+    }
+
+}
diff --git a/awt/java/awt/Composite.java b/awt/java/awt/Composite.java
new file mode 100644
index 0000000..8e5b90a
--- /dev/null
+++ b/awt/java/awt/Composite.java
@@ -0,0 +1,47 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.ColorModel;
+
+/**
+ * The Composite interface allows the methods to compose a draw primitive 
+ * on the graphics area. The classes implementing this interface provides 
+ * the rules and a method to create the context for a particular operation.
+ */
+public interface Composite {
+
+    /**
+     * Creates a CompositeContext which defines the encapsulated and 
+     * optimized environment for a compositing operation. Several contexts 
+     * can exist for a single Composite object.
+     * 
+     * @param srcColorModel the source's ColorModel.
+     * @param dstColorModel the destination's ColorModel.
+     * @param hints the RenderingHints.
+     * 
+     * @return the CompositeContext object.
+     */
+    public CompositeContext createContext(ColorModel srcColorModel,
+            ColorModel dstColorModel, RenderingHints hints);
+
+}
+
diff --git a/awt/java/awt/CompositeContext.java b/awt/java/awt/CompositeContext.java
new file mode 100644
index 0000000..c676032
--- /dev/null
+++ b/awt/java/awt/CompositeContext.java
@@ -0,0 +1,49 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+/**
+ * The CompositeContext interface specifies the encapsulated and optimized 
+ * environment for a compositing operation. 
+ */
+public interface CompositeContext {
+
+    /**
+     * Composes the two source Raster objects and places the result in the 
+     * destination WritableRaster. 
+     * 
+     * @param src the source Raster.
+     * @param dstIn the destination Raster.
+     * @param dstOut the WritableRaster object where the result of
+     * composing operation is stored.
+     */
+    public void compose(Raster src, Raster dstIn, WritableRaster dstOut);
+
+    /**
+     * Releases resources allocated for a context.
+     */
+    public void dispose();
+
+}
+
diff --git a/awt/java/awt/Cursor.java b/awt/java/awt/Cursor.java
new file mode 100644
index 0000000..625686c
--- /dev/null
+++ b/awt/java/awt/Cursor.java
@@ -0,0 +1,372 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.NativeCursor;
+
+/**
+ * The Cursor class represents the bitmap of the mouse cursor.
+ */
+public class Cursor implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8028237497568985504L;
+    
+    /** The Constant DEFAULT_CURSOR indicates the default cursor type. */
+    public static final int DEFAULT_CURSOR = 0;
+
+    /** The Constant CROSSHAIR_CURSOR cursor type. */
+    public static final int CROSSHAIR_CURSOR = 1;
+
+    /** The Constant TEXT_CURSOR cursor type. */
+    public static final int TEXT_CURSOR = 2;
+
+    /** The Constant WAIT_CURSOR cursor type. */
+    public static final int WAIT_CURSOR = 3;
+
+    /** The Constant SW_RESIZE_CURSOR cursor type. */
+    public static final int SW_RESIZE_CURSOR = 4;
+
+    /** The Constant SE_RESIZE_CURSOR cursor type. */
+    public static final int SE_RESIZE_CURSOR = 5;
+
+    /** The Constant NW_RESIZE_CURSOR cursor type. */
+    public static final int NW_RESIZE_CURSOR = 6;
+
+    /** The Constant NE_RESIZE_CURSOR cursor type. */
+    public static final int NE_RESIZE_CURSOR = 7;
+
+    /** The Constant N_RESIZE_CURSOR cursor type. */
+    public static final int N_RESIZE_CURSOR = 8;
+
+    /** The Constant S_RESIZE_CURSOR cursor type. */
+    public static final int S_RESIZE_CURSOR = 9;
+
+    /** The Constant W_RESIZE_CURSOR cursor type. */
+    public static final int W_RESIZE_CURSOR = 10;
+
+    /** The Constant E_RESIZE_CURSOR cursor type. */
+    public static final int E_RESIZE_CURSOR = 11;
+
+    /** The Constant HAND_CURSOR cursor type. */
+    public static final int HAND_CURSOR = 12;
+
+    /** The Constant MOVE_CURSOR cursor type. */
+    public static final int MOVE_CURSOR = 13;
+
+    /** A mapping from names to system custom cursors. */
+    static Map<String, Cursor> systemCustomCursors;
+    
+    /** The cursor props. */
+    static Properties cursorProps;
+
+    /** The Constant predefinedNames. */
+    static final String[] predefinedNames = {
+            "Default", "Crosshair", "Text", "Wait", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            "Southwest Resize", "Southeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
+            "Northwest Resize", "Northeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
+            "North Resize", "South Resize", "West Resize", "East Resize", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            "Hand", "Move" //$NON-NLS-1$ //$NON-NLS-2$
+
+    };
+
+    /** The predefined set of cursors. */
+    protected static Cursor[] predefined = {
+            new Cursor(DEFAULT_CURSOR), null, null, null,
+            null, null, null, null,
+            null, null, null, null,
+            null, null
+    };
+
+    /** The Constant CUSTOM_CURSOR is associated with all custom cursor types. 
+     * (Those which are not predefined)
+     */
+    public static final int CUSTOM_CURSOR = -1;
+
+    /** The name of the cursor. */
+    protected String name;
+
+    /** The type of the cursor, chosen from the list of cursor type constants. */
+    private final int type;
+    
+    /** The native cursor. */
+    private transient NativeCursor nativeCursor;
+    
+    /** The exact point on the cursor image that indicates which point 
+     * the cursor is selecting (pointing to). The coordinates are given 
+     * with respect the origin of the Image (its upper left corner).
+     */
+    private Point hotSpot;
+    
+    /** The image to draw on the screen representing the cursor. */
+    private Image image;
+
+    /**
+     * Instantiates a new cursor with the specified name.
+     * 
+     * @param name the name of cursor.
+     */
+    protected Cursor(String name) {
+        this(name, null, new Point());
+    }
+
+    /**
+     * Instantiates a new cursor of the specified type.
+     * 
+     * @param type the type of cursor.
+     */
+    public Cursor(int type) {
+        checkType(type);
+        this.type = type;
+        if ((type >= 0) && (type < predefinedNames.length)) {
+            name = predefinedNames[type] + " Cursor"; //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Instantiates a new cursor.
+     * 
+     * @param name the name
+     * @param img the img
+     * @param hotSpot the hot spot
+     */
+    Cursor(String name, Image img, Point hotSpot) {
+        this.name = name;
+        type = CUSTOM_CURSOR;
+        this.hotSpot = hotSpot;
+        image = img;
+    }
+
+    /**
+     * Finalize method overrided finalize method from Object class.
+     * 
+     * @throws Throwable if the native cursor is not null and throws
+     * a throwable when destroyed.
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        if (nativeCursor != null) {
+            nativeCursor.destroyCursor();
+        }
+    }
+
+    /**
+     * Gets the name of the cursor.
+     * 
+     * @return the name of the cursor.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the String representation of the cursor.
+     * 
+     * @return the String representation of the cursor.
+     */
+    @Override
+    public String toString() {
+        return getClass().getName() + "[" + name + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets the cursor type.
+     * 
+     * @return the cursor type
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Gets the predefined cursor with the specified type.
+     * 
+     * @param type the type of cursor.
+     * 
+     * @return the predefined cursor with the specified type.
+     */
+    public static Cursor getPredefinedCursor(int type) {
+        checkType(type);
+        Cursor cursor = predefined[type];
+        if (cursor == null) {
+            cursor = new Cursor(type);
+            predefined[type] = cursor;
+        }
+        return cursor;
+    }
+
+    /**
+     * Gets the default cursor.
+     * 
+     * @return the default cursor.
+     */
+    public static Cursor getDefaultCursor() {
+        return getPredefinedCursor(DEFAULT_CURSOR);
+    }
+
+    /**
+     * Gets the specified system custom cursor.
+     * 
+     * @param name the name of the desired system cursor.
+     * 
+     * @return the specific system cursor with the specified name.
+     * 
+     * @throws AWTException if the desired cursor has malformed data
+     * such as an incorrectly defined hot spot.
+     * @throws HeadlessException if the isHeadless method of the GraphicsEnvironment
+     * returns true.
+     */
+    public static Cursor getSystemCustomCursor(String name)
+    throws AWTException, HeadlessException {
+        Toolkit.checkHeadless();
+        return getSystemCustomCursorFromMap(name);
+    }
+
+    /**
+     * Gets the specified system custom cursor from the map of system custom cursors.
+     * 
+     * @param name the name of the desired cursor.
+     * 
+     * @return the desired system custom cursor from the 
+     * map of system custom cursors.
+     * 
+     * @throws AWTException the AWT exception
+     */
+    private static Cursor getSystemCustomCursorFromMap (String name)
+    throws AWTException {
+        loadCursorProps();
+        if (systemCustomCursors == null) {
+            systemCustomCursors = new HashMap<String, Cursor>();
+        }
+        Cursor cursor = systemCustomCursors.get(name);
+        if (cursor != null) {
+            return cursor;
+        }
+        // awt.141=failed to parse hotspot property for cursor:
+        String exMsg = Messages.getString("awt.141") + name; //$NON-NLS-1$
+        String nm = "Cursor." + name; //$NON-NLS-1$
+        String nameStr = cursorProps.getProperty(nm + ".Name"); //$NON-NLS-1$
+        String hotSpotStr = cursorProps.getProperty(nm + ".HotSpot"); //$NON-NLS-1$
+        String fileStr = cursorProps.getProperty(nm + ".File"); //$NON-NLS-1$
+        int idx = hotSpotStr.indexOf(',');
+        if (idx < 0) {
+            throw new AWTException(exMsg);
+        }
+        int x, y;
+        try {
+            x = new Integer(hotSpotStr.substring(0, idx)).intValue();
+            y = new Integer(hotSpotStr.substring(idx + 1,
+                                                 hotSpotStr.length())).intValue();
+        } catch (NumberFormatException nfe) {
+            throw new AWTException(exMsg);
+        }
+        Image img = Toolkit.getDefaultToolkit().createImage(fileStr);
+        cursor = new Cursor(nameStr, img, new Point(x, y));
+        systemCustomCursors.put(name, cursor);
+
+        return cursor;
+    }
+
+    /**
+     * Load cursor props.
+     * 
+     * @throws AWTException the AWT exception
+     */
+    private static void loadCursorProps() throws AWTException {
+        if (cursorProps != null) {
+            return;
+        }
+        String sep = File.separator;
+        String cursorsDir = "lib" + sep + "images" + sep + "cursors"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        String cursorsAbsDir = System.getProperty("java.home") + sep + //$NON-NLS-1$
+                                cursorsDir;
+        String cursorPropsFileName = "cursors.properties"; //$NON-NLS-1$
+        String cursorPropsFullFileName = (cursorsAbsDir + sep +
+                                          cursorPropsFileName);
+        cursorProps = new Properties();
+        try {
+            cursorProps.load(new FileInputStream(new File(
+                    cursorPropsFullFileName)));
+        } catch (FileNotFoundException e) {
+            // awt.142=Exception: class {0} {1} occurred while loading: {2}
+            throw new AWTException(Messages.getString("awt.142",//$NON-NLS-1$
+                      new Object[]{e.getClass(), e.getMessage(), cursorPropsFullFileName}));
+        } catch (IOException e) {
+            throw new AWTException(e.getMessage());
+        }
+
+    }
+
+    /**
+     * Check type.
+     * 
+     * @param type the type
+     */
+    static void checkType(int type) {
+        // can't use predefined array here because it may not have been
+        // initialized yet
+        if ((type < 0) || (type >= predefinedNames.length)) {
+            // awt.143=illegal cursor type
+            throw new IllegalArgumentException(Messages.getString("awt.143")); //$NON-NLS-1$
+        }
+    }
+
+    // "lazily" create native cursors:
+    /**
+     * Gets the native cursor.
+     * 
+     * @return the native cursor
+     */
+    NativeCursor getNativeCursor() {
+        if (nativeCursor != null) {
+            return nativeCursor;
+        }
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        if (type != CUSTOM_CURSOR) {
+            nativeCursor = toolkit.createNativeCursor(type);
+        } else {
+            nativeCursor = toolkit.createCustomNativeCursor(image, hotSpot,
+                                                            name);
+        }
+        return nativeCursor;
+    }
+
+    /**
+     * Sets the native cursor.
+     * 
+     * @param nativeCursor the new native cursor
+     */
+    void setNativeCursor(NativeCursor nativeCursor) {
+        this.nativeCursor = nativeCursor;
+    }
+}
+
diff --git a/awt/java/awt/Dimension.java b/awt/java/awt/Dimension.java
new file mode 100644
index 0000000..8137846
--- /dev/null
+++ b/awt/java/awt/Dimension.java
@@ -0,0 +1,185 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.Dimension2D;
+import java.io.Serializable;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Dimension represents the size (width and height) of a component.
+ * The width and height values can be negative, but in that case the 
+ * behavior of some methods is unexpected. 
+ */
+public class Dimension extends Dimension2D implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 4723952579491349524L;
+
+    /** The width dimension. */
+    public int width;
+    
+    /** The height dimension. */
+    public int height;
+
+    /**
+     * Instantiates a new Dimension with the same data as the specified Dimension.
+     * 
+     * @param d the Dimension to copy the data from when creating the 
+     * new Dimension object.
+     */
+    public Dimension(Dimension d) {
+        this(d.width, d.height);
+    }
+
+    /**
+     * Instantiates a new Dimension with zero width and height.
+     */
+    public Dimension() {
+        this(0, 0);
+    }
+
+    /**
+     * Instantiates a new Dimension with the specified width and height.
+     * 
+     * @param width the width of the new Dimension.
+     * @param height the height of the new Dimension.
+     */
+    public Dimension(int width, int height) {
+        setSize(width, height);
+    }
+
+    /**
+     * Returns the hash code of the Dimension.
+     * 
+     * @return the hash code of the Dimension.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(width);
+        hash.append(height);
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this Dimension object with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is a Dimension with 
+     * the same width and height data as this Dimension. 
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Dimension) {
+            Dimension d = (Dimension)obj;
+            return (d.width == width && d.height == height);
+        }
+        return false;
+    }
+
+    /**
+     * Returns the String associated to this Dimension object.
+     * 
+     * @return the String associated to this Dimension object.
+     */
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. It could be obtained in the following way
+        // System.out.println(new Dimension().toString())
+        return getClass().getName() + "[width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Sets the size of this Dimension object with the specified width and height.
+     * 
+     * @param width the width of the Dimension.
+     * @param height the height of the Dimension.
+     */
+    public void setSize(int width, int height) {
+        this.width = width;
+        this.height = height;
+    }
+
+    /**
+     * Sets the size of this Dimension object by copying the 
+     * data from the specified Dimension object.
+     * 
+     * @param d the Dimension that gives the new size values.
+     */
+    public void setSize(Dimension d) {
+        setSize(d.width, d.height);
+    }
+
+    /**
+     * Sets the size of this Dimension object with the specified double width 
+     * and height.
+     * 
+     * @param width the width of the Dimension.
+     * @param height the height of the Dimension.
+     * 
+     * @see java.awt.geom.Dimension2D#setSize(double, double)
+     */
+    @Override
+    public void setSize(double width, double height) {
+        setSize((int)Math.ceil(width), (int)Math.ceil(height));
+    }
+
+    /**
+     * Gets the size of the Dimension.
+     * 
+     * @return the size of the Dimension.
+     */
+    public Dimension getSize() {
+        return new Dimension(width, height);
+    }
+
+    /**
+     * Gets the height of the Dimension.
+     * 
+     * @return the height of the Dimension.
+     * 
+     * @see java.awt.geom.Dimension2D#getHeight()
+     */
+    @Override
+    public double getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the width of the Dimension.
+     * 
+     * @return the width of the Dimension.
+     * 
+     * @see java.awt.geom.Dimension2D#getWidth()
+     */
+    @Override
+    public double getWidth() {
+        return width;
+    }
+
+}
+
diff --git a/awt/java/awt/Dispatcher.java b/awt/java/awt/Dispatcher.java
new file mode 100644
index 0000000..d457af4
--- /dev/null
+++ b/awt/java/awt/Dispatcher.java
@@ -0,0 +1,723 @@
+/*
+ *  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 Michael Danilov, Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.ComponentEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.PaintEvent;
+import java.awt.event.WindowEvent;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.NativeEvent;
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+
+/**
+ * Helper package-private class for managing lightweight components &
+ * dispatching events from heavyweight source
+ */
+class Dispatcher {
+
+    //???AWT: final PopupDispatcher popupDispatcher = new PopupDispatcher();
+
+    //???AWT: final FocusDispatcher focusDispatcher;
+
+    final MouseGrabManager mouseGrabManager = new MouseGrabManager();
+
+    final MouseDispatcher mouseDispatcher;
+
+    private final ComponentDispatcher componentDispatcher = new ComponentDispatcher();
+
+    private final KeyDispatcher keyDispatcher = new KeyDispatcher();
+
+    private final Toolkit toolkit;
+
+    int clickInterval = 250;
+
+    /**
+     * @param toolkit - AWT toolkit
+     */
+    Dispatcher(Toolkit toolkit) {
+        this.toolkit = toolkit;
+
+        //???AWT: focusDispatcher = new FocusDispatcher(toolkit);
+        mouseDispatcher = new MouseDispatcher(mouseGrabManager, toolkit);
+    }
+
+    /**
+     * Dispatch native event: produce appropriate AWT events, 
+     * update component's fields when needed
+     * @param event - native event to dispatch
+     * @return - true means default processing by OS is not needed
+     */
+    public boolean onEvent(NativeEvent event) {
+        int eventId = event.getEventId();
+
+        if (eventId == NativeEvent.ID_CREATED) {
+            return toolkit.onWindowCreated(event.getWindowId());
+        } else if (eventId == NativeEvent.ID_MOUSE_GRAB_CANCELED) {
+            return mouseGrabManager.onGrabCanceled();
+        //???AWT
+//        } else if (popupDispatcher.onEvent(event)) {
+//            return false;
+        } else {
+            Component src = toolkit.getComponentById(event.getWindowId());
+
+            if (src != null) {
+                if (((eventId >= ComponentEvent.COMPONENT_FIRST) && (eventId <= ComponentEvent.COMPONENT_LAST))
+                        || ((eventId >= WindowEvent.WINDOW_FIRST) && (eventId <= WindowEvent.WINDOW_LAST))
+                        || (eventId == NativeEvent.ID_INSETS_CHANGED)
+                        || (eventId == NativeEvent.ID_BOUNDS_CHANGED)
+                        || (eventId == NativeEvent.ID_THEME_CHANGED)) {
+                    return componentDispatcher.dispatch(src, event);
+                } else if ((eventId >= MouseEvent.MOUSE_FIRST)
+                        && (eventId <= MouseEvent.MOUSE_LAST)) {
+                    return mouseDispatcher.dispatch(src, event);
+                } else if (eventId == PaintEvent.PAINT) {
+                    //???AWT: src.redrawManager.addPaintRegion(src, event.getClipRects());
+                    return true;
+                }
+            }
+            if ((eventId >= FocusEvent.FOCUS_FIRST)
+                    && (eventId <= FocusEvent.FOCUS_LAST)) {
+
+                //???AWT: return focusDispatcher.dispatch(src, event);
+                return false;
+            } else if ((eventId >= KeyEvent.KEY_FIRST)
+                    && (eventId <= KeyEvent.KEY_LAST)) {
+                return keyDispatcher.dispatch(src, event);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * The dispatcher of native events that affect 
+     * component's state or bounds
+     */
+    final class ComponentDispatcher {
+
+        /**
+         * Handle native event that affects component's state or bounds
+         * @param src - the component updated by the event
+         * @param event - the native event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatch(Component src, NativeEvent event) {
+            int id = event.getEventId();
+
+            if ((id == NativeEvent.ID_INSETS_CHANGED)
+                    || (id == NativeEvent.ID_THEME_CHANGED)) {
+                return dispatchInsets(event, src);
+            } else if ((id >= WindowEvent.WINDOW_FIRST)
+                    && (id <= WindowEvent.WINDOW_LAST)) {
+                return dispatchWindow(event, src);
+            } else {
+                return dispatchPureComponent(event, src);
+            }
+        }
+
+        /**
+         * Handle the change of top-level window's native decorations 
+         * @param event - the native event
+         * @param src - the component updated by the event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatchInsets(NativeEvent event, Component src) {
+            //???AWT
+            /*
+            if (src instanceof Window) {
+                ((Window) src).setNativeInsets(event.getInsets());
+            }
+            */
+            return false;
+        }
+
+        /**
+         * Handle the change of top-level window's state
+         * @param event - the native event
+         * @param src - the component updated by the event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatchWindow(NativeEvent event, Component src) {
+            //???AWT
+            /*
+            Window window = (Window) src;
+            int id = event.getEventId();
+
+            if (id == WindowEvent.WINDOW_CLOSING) {
+                toolkit.getSystemEventQueueImpl().postEvent(
+                          new WindowEvent(window, WindowEvent.WINDOW_CLOSING));
+
+                return true;
+            } else if (id == WindowEvent.WINDOW_STATE_CHANGED) {
+                if (window instanceof Frame) {
+                    ((Frame) window)
+                            .updateExtendedState(event.getWindowState());
+                }
+            }
+            */
+
+            return false;
+        }
+
+        /**
+         * Handle the change of component's size and/or position
+         * @param event - the native event
+         * @param src - the component updated by the event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        private boolean dispatchPureComponent(NativeEvent event, Component src) {
+            Rectangle rect = event.getWindowRect();
+            Point loc = rect.getLocation();
+            int mask;
+
+            switch (event.getEventId()) {
+            case NativeEvent.ID_BOUNDS_CHANGED:
+                mask = 0;
+                break;
+            case ComponentEvent.COMPONENT_MOVED:
+                mask = NativeWindow.BOUNDS_NOSIZE;
+                break;
+            case ComponentEvent.COMPONENT_RESIZED:
+                mask = NativeWindow.BOUNDS_NOMOVE;
+                break;
+            default:
+                // awt.12E=Unknown component event id.
+                throw new RuntimeException(Messages.getString("awt.12E")); //$NON-NLS-1$
+            }
+
+            //???AWT
+            /*
+            if (!(src instanceof Window)) {
+                Component compTo = src.getParent();
+                Component compFrom = src.getHWAncestor();
+
+                if ((compTo != null) && (compFrom != null)) {
+                    loc = MouseDispatcher.convertPoint(compFrom, loc, compTo);
+                }
+            } else {
+                int windowState = event.getWindowState();
+
+                if ((windowState >= 0) && (src instanceof Frame)) {
+                    ((Frame) src).updateExtendedState(windowState);
+                }
+            }
+            src.setBounds(loc.x, loc.y, rect.width, rect.height, mask, false);
+            */
+            
+            return false;
+        }
+
+    }
+
+    /**
+     * The dispatcher of the keyboard events
+     */
+    final class KeyDispatcher {
+
+        /**
+         * Handle the keyboard event using the KeyboardFocusManager
+         * @param src - the component receiving the event
+         * @param event - the native event
+         * @return - as in Dispatcher.onEvent()
+         * @see Dispatcher#onEvent(NativeEvent)
+         */
+        boolean dispatch(Component src, NativeEvent event) {
+            int id = event.getEventId();
+            int modifiers = event.getInputModifiers();
+            int location = event.getKeyLocation();
+            int code = event.getVKey();
+            StringBuffer chars = event.getKeyChars();
+            int charsLength = chars.length();
+            long time = event.getTime();
+            char keyChar = event.getLastChar();
+
+            //???AWT
+            /*
+            if (src == null) {
+                //retarget focus proxy key events to focusOwner:
+                Window focusProxyOwner = toolkit.getFocusProxyOwnerById(event
+                        .getWindowId());
+                if (focusProxyOwner == null) {
+                    return false;
+                }
+                src = KeyboardFocusManager.actualFocusOwner;
+            }
+            */
+
+            EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
+            
+            if (src != null) {
+                eventQueue.postEvent(new KeyEvent(src, id, time, modifiers,
+                        code, keyChar, location));
+                // KEY_TYPED goes after KEY_PRESSED
+                if (id == KeyEvent.KEY_PRESSED) {
+                    for (int i = 0; i < charsLength; i++) {
+                        keyChar = chars.charAt(i);
+                        if (keyChar != KeyEvent.CHAR_UNDEFINED) {
+                            eventQueue.postEvent(new KeyEvent(src,
+                                    KeyEvent.KEY_TYPED, time, modifiers,
+                                    KeyEvent.VK_UNDEFINED, keyChar,
+                                    KeyEvent.KEY_LOCATION_UNKNOWN));
+                        }
+                    }
+                }
+            }
+
+            return false;
+        }
+
+    }
+
+    /**
+     * Retargets the mouse events to the grab owner when mouse is grabbed,
+     * grab and ungrab mouse when mouse buttons are pressed and released
+     */
+
+    static final class MouseGrabManager {
+
+        /** 
+         * The top-level window holding the mouse grab 
+         * that was explicitly started by startGrab() method
+         */
+        //???AWT: private Window nativeGrabOwner = null;
+        /** 
+         * The component that owns the synthetic 
+         * mouse grab while at least one of the
+         * mouse buttons is pressed
+         */
+        private Component syntheticGrabOwner = null;
+
+        /**
+         * Previous value of syntheticGrabOwner
+         */
+        private Component lastSyntheticGrabOwner = null;
+
+        /**
+         * Number of mouse buttons currently pressed
+         */
+        private int syntheticGrabDepth = 0;
+
+        /**
+         * The callback to be called when the explicit mouse grab ends
+         */
+        private Runnable whenCanceled;
+
+        /**
+         * Explicitly start the mouse grab
+         * @param grabWindow - the window that will own the grab
+         * @param whenCanceled - the callback to call when the grab ends. 
+         * This parameter can be null
+         */
+        //???AWT
+        /*
+        void startGrab(Window grabWindow, Runnable whenCanceled) {
+
+            if (nativeGrabOwner != null) {
+                // awt.12F=Attempt to start nested mouse grab
+                throw new RuntimeException(Messages.getString("awt.12F")); //$NON-NLS-1$
+            }
+
+            NativeWindow win = grabWindow.getNativeWindow();
+            if (win == null) {
+                // awt.130=Attempt to grab mouse in not displayable window
+                throw new RuntimeException(Messages.getString("awt.130")); //$NON-NLS-1$
+            }
+
+            nativeGrabOwner = grabWindow;
+            this.whenCanceled = whenCanceled;
+            win.grabMouse();
+        }
+        */
+
+        /**
+         * Ends the explicit mouse grab. If the non-null callback was provided
+         * in the startGrab() method, this callback is called 
+         */
+        void endGrab() {
+            //???AWT
+            /*
+            if (nativeGrabOwner == null) {
+                return;
+            }
+
+            Window grabWindow = nativeGrabOwner;
+            nativeGrabOwner = null;
+            NativeWindow win = grabWindow.getNativeWindow();
+
+            if (win != null) {
+                win.ungrabMouse();
+                if (whenCanceled != null) {
+                    whenCanceled.run();
+                    whenCanceled = null;
+                }
+            }
+            */
+        }
+
+        /**
+         * Ends both explicit and synthetic grans 
+         * @return - always returns false
+         */
+        boolean onGrabCanceled() {
+            endGrab();
+            resetSyntheticGrab();
+
+            return false;
+        }
+
+        /**
+         * Starts the synthetic mouse grab, increases the counter 
+         * of currently pressed mouse buttons
+         * @param source - the component where mouse press event occured
+         * @return - the component that owns the synthetic grab
+         */
+        Component onMousePressed(Component source) {
+            if (syntheticGrabDepth == 0) {
+                syntheticGrabOwner = source;
+                lastSyntheticGrabOwner = source;
+            }
+            syntheticGrabDepth++;
+
+            return syntheticGrabOwner;
+        }
+
+        /**
+         * Decreases the counter of currently pressed mouse buttons,
+         * ends the synthetic mouse grab, when this counter becomes zero
+         * @param source - the component where mouse press event occured
+         * @return - the component that owns the synthetic grab, 
+         * or source parameter if mouse grab was released
+         */
+        Component onMouseReleased(Component source) {
+            Component ret = source;
+
+            //???AWT
+            /*
+            if (syntheticGrabOwner != null && nativeGrabOwner == null) {
+                ret = syntheticGrabOwner;
+            }
+            */
+            syntheticGrabDepth--;
+            if (syntheticGrabDepth <= 0) {
+                resetSyntheticGrab();
+                lastSyntheticGrabOwner = null;
+            }
+
+            return ret;
+        }
+
+        /**
+         * Update the state of synthetic ouse gram 
+         * when the mouse is moved/dragged
+         * @param event - the native event
+         */
+        void preprocessEvent(NativeEvent event) {
+            int id = event.getEventId();
+            switch (id) {
+            case MouseEvent.MOUSE_MOVED:
+                if (syntheticGrabOwner != null) {
+                    syntheticGrabOwner = null;
+                    syntheticGrabDepth = 0;
+                }
+                if (lastSyntheticGrabOwner != null) {
+                    lastSyntheticGrabOwner = null;
+                }
+            case MouseEvent.MOUSE_DRAGGED:
+                if (syntheticGrabOwner == null
+                        && lastSyntheticGrabOwner != null) {
+                    syntheticGrabOwner = lastSyntheticGrabOwner;
+                    syntheticGrabDepth = 0;
+                    int mask = event.getInputModifiers();
+                    syntheticGrabDepth += (mask & InputEvent.BUTTON1_DOWN_MASK) != 0 ? 1
+                            : 0;
+                    syntheticGrabDepth += (mask & InputEvent.BUTTON2_DOWN_MASK) != 0 ? 1
+                            : 0;
+                    syntheticGrabDepth += (mask & InputEvent.BUTTON3_DOWN_MASK) != 0 ? 1
+                            : 0;
+                }
+            }
+        }
+
+        /**
+         * @return the component that currently owns the synthetic grab 
+         */
+        Component getSyntheticGrabOwner() {
+            return syntheticGrabOwner;
+        }
+
+        /**
+         * ends synthetic grab
+         */
+        private void resetSyntheticGrab() {
+            syntheticGrabOwner = null;
+            syntheticGrabDepth = 0;
+        }
+
+    }
+    
+    /**
+     * Dispatches native events related to the pop-up boxes 
+     * (the non-component windows such as menus and drop lists)
+     */
+//    final class PopupDispatcher {
+//
+//        private PopupBox activePopup;
+//
+//        private PopupBox underCursor;
+//
+//        private final MouseGrab grab = new MouseGrab();
+//
+//        /**
+//         * Handles the mouse grab for pop-up boxes
+//         */
+//        private final class MouseGrab {
+//            private int depth;
+//
+//            private PopupBox owner;
+//
+//            private final Point start = new Point();
+//
+//            /**
+//             * Starts the grab when mouse is pressed
+//             * @param src - the pop-up box where mouse event has occured
+//             * @param where - the mouse pointer location
+//             * @return - the grab owner
+//             */
+//            PopupBox mousePressed(PopupBox src, Point where) {
+//                if (depth == 0) {
+//                    owner = src;
+//                    start.setLocation(where);
+//                }
+//                depth++;
+//                return owner;
+//            }
+//
+//            /**
+//             * Ends the grab when all mousebuttons are released
+//             * @param src - the pop-up box where mouse event has occured
+//             * @param where - the mouse pointer location
+//             * @return - the grab owner, or src parameter if the grab has ended
+//             */
+//            PopupBox mouseReleased(PopupBox src, Point where) {
+//                PopupBox ret = (owner != null) ? owner : src;
+//                if (depth == 0) {
+//                    return ret;
+//                }
+//                depth--;
+//                if (depth == 0) {
+//                    PopupBox tgt = owner;
+//                    owner = null;
+//                    if (tgt != null && src == null) {
+//                        Point a = new Point(start);
+//                        Point b = new Point(where);
+//                        Point pos = tgt.getScreenLocation();
+//                        a.translate(-pos.x, -pos.y);
+//                        b.translate(-pos.x, -pos.y);
+//                        if (tgt.closeOnUngrab(a, b)) {
+//                            return null;
+//                        }
+//                    }
+//                }
+//                return ret;
+//            }
+//
+//            /**
+//             * Set the grab owner to null
+//             */
+//            void reset() {
+//                depth = 0;
+//                owner = null;
+//                start.setLocation(0, 0);
+//            }
+//
+//            /**
+//             * @return - the pop-up box currently owning the grab
+//             */
+//            public PopupBox getOwner() {
+//                return owner;
+//            }
+//        }
+//
+//        /**
+//         * Call the mouse event handler of the pop-up box
+//         * @param src - the pop-up box where the mouse event occured
+//         * @param eventId - the event ID, one of MouseEvent.MOUSE_* constants
+//         * @param where - the mouse pointer location
+//         * @param event - native event
+//         */
+//        private void mouseEvent(PopupBox src, int eventId, Point where,
+//                NativeEvent event) {
+//            Point pos = src.getScreenLocation();
+//            pos.setLocation(where.x - pos.x, where.y - pos.y);
+//
+//            src.onMouseEvent(eventId, pos, event.getMouseButton(), event
+//                    .getTime(), event.getInputModifiers(), event
+//                    .getWheelRotation());
+//        }
+//
+//        /**
+//         * Handle the native event targeted by a pop-up box. This could be 
+//         * paint event, mouse or keyboard event.
+//         * @param event - the native event
+//         * @return - false if the event was handled and doesn't 
+//         * need the further processing; true when the further 
+//         * processing is needed
+//         */
+//        boolean onEvent(NativeEvent event) {
+//            PopupBox src = toolkit.getPopupBoxById(event.getWindowId());
+//            int id = event.getEventId();
+//
+//            if ((id == PaintEvent.PAINT)) {
+//                if (src != null) {
+//                    src.paint(event.getClipRects());
+//                    return true;
+//                }
+//                Component c = toolkit.getComponentById(event.getWindowId());
+//                if ((c != null) && (c instanceof Frame)) {
+//                    ((Frame) c).paintMenuBar(event.getClipRects());
+//                }
+//                return false;
+//            }
+//
+//            if ((id >= MouseEvent.MOUSE_FIRST) && (id <= MouseEvent.MOUSE_LAST)) {
+//                Point where = event.getScreenPos();
+//
+//                if (src != underCursor) {
+//                    if (underCursor != null) {
+//                        mouseEvent(underCursor, MouseEvent.MOUSE_EXITED, where,
+//                                event);
+//                    }
+//                    underCursor = src;
+//                    if (underCursor != null) {
+//                        mouseEvent(underCursor, MouseEvent.MOUSE_ENTERED,
+//                                where, event);
+//                        underCursor.setDefaultCursor();
+//                    }
+//                }
+//                if (id == MouseEvent.MOUSE_EXITED) {
+//                    underCursor = null;
+//                }
+//
+//                if ((activePopup == null) && (src == null || !src.isMenuBar())) {
+//                    return false;
+//                }
+//
+//                if (id == MouseEvent.MOUSE_PRESSED) {
+//                    src = grab.mousePressed(src, where);
+//                } else if (id == MouseEvent.MOUSE_RELEASED) {
+//                    src = grab.mouseReleased(src, where);
+//                } else if (src == null) {
+//                    src = grab.getOwner();
+//                }
+//
+//                PopupBox wasActive = activePopup;
+//
+//                if (src != null) {
+//                    mouseEvent(src, id, where, event);
+//                    return src.isMenu() || src.contains(where);
+//                }
+//
+//                if (wasActive != null && activePopup == null) {
+//                    return wasActive.isMenu();
+//                }
+//
+//                if ((id == MouseEvent.MOUSE_PRESSED)
+//                        || (id == MouseEvent.MOUSE_RELEASED)) {
+//                    boolean isMenu = activePopup.isMenu();
+//                    deactivateAll();
+//                    return !isMenu;
+//                }
+//                return true;
+//            }
+//
+//            if (activePopup == null) {
+//                return false;
+//            }
+//
+//            if ((id >= KeyEvent.KEY_FIRST) && (id <= KeyEvent.KEY_LAST)) {
+//                boolean isMenu = activePopup.isMenu();
+//                activePopup.dispatchKeyEvent(id, event.getVKey(), event
+//                        .getTime(), event.getInputModifiers());
+//
+//                return isMenu;
+//            }
+//
+//            return false;
+//        }
+//
+//        /**
+//         * Remember the pop-up as active and grab the mouse on it
+//         * @param popup - the pop-up box to activate
+//         */
+//        void activate(final PopupBox popup) {
+//            if (activePopup == null) {
+//
+//                activePopup = popup;
+//                mouseGrabManager.startGrab(popup.getOwner(), new Runnable() {
+//                    public void run() {
+//                        deactivate(popup);
+//                    }
+//                });
+//            }
+//        }
+//
+//        /**
+//         * Deactivate the currently active pop-up box
+//         */
+//        void deactivateAll() {
+//            deactivate(activePopup);
+//        }
+//
+//        /**
+//         * Deactivate the pop-up box, end the mouse grab
+//         */
+//        void deactivate(PopupBox popup) {
+//            grab.reset();
+//
+//            if (activePopup != null && activePopup == popup) {
+//                activePopup = null;
+//                mouseGrabManager.endGrab();
+//                popup.hide();
+//                underCursor = null;
+//            }
+//        }
+//
+//        /**
+//         * Check that the pop-up box is currently active
+//         * @param popup - the pop-up box to check
+//         * @return - true if active
+//         */
+//        boolean isActive(PopupBox popup) {
+//            return (popup == activePopup) && (popup != null);
+//        }
+//    }
+
+}
\ No newline at end of file
diff --git a/awt/java/awt/DisplayMode.java b/awt/java/awt/DisplayMode.java
new file mode 100644
index 0000000..082c7b8
--- /dev/null
+++ b/awt/java/awt/DisplayMode.java
@@ -0,0 +1,147 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The DisplayMode class containes the bit depth, height, width and 
+ * refresh rate of a GraphicsDevice.
+ */
+public final class DisplayMode {
+    
+    /** The width. */
+    private final int width;
+
+    /** The height. */
+    private final int height;
+
+    /** The bit depth. */
+    private final int bitDepth;
+
+    /** The refresh rate. */
+    private final int refreshRate;
+
+   /** The Constant Value BIT_DEPTH_MULTI indicates the bit depth */
+
+    public static final int BIT_DEPTH_MULTI = -1;
+
+    /** The Constant REFRESH_RATE_UNKNOWN indicates the refresh rate. */
+    public static final int REFRESH_RATE_UNKNOWN = 0;
+
+   /**
+    * Creates a new DisplayMode object with the specified parameters.
+    *  
+    * @param width the width of the display.
+    * @param height the height of the display.
+    * @param bitDepth the bit depth of the display.
+    * @param refreshRate the refresh rate of the display.
+    */
+
+    public DisplayMode(int width, int height, int bitDepth, int refreshRate) {
+        this.width = width;
+        this.height = height;
+        this.bitDepth = bitDepth;
+        this.refreshRate = refreshRate;
+    }
+
+
+   /**
+    * Compares if this DisplayMode is equal to the specified object or not.
+    * 
+    * @param dm the Object to be compared.
+    * 
+    * @return true, if the specified object is a DisplayMode with the same
+    * data values as this DisplayMode, false otherwise.
+    */
+
+    @Override
+    public boolean equals(Object dm) {
+        if (dm instanceof DisplayMode) {
+            return equals((DisplayMode)dm);
+        }
+        return false;
+    }
+
+    /**
+    * Compares if this DisplayMode is equal to the specified DisplayMode object
+    * or not.
+    * 
+    * @param dm the DisplayMode to be compared.
+    * 
+    * @return true, if all of the data values of this DisplayMode are equal 
+    * to the values of the specified DisplayMode object, false otherwise.
+     */
+    public boolean equals(DisplayMode dm) {
+        if (dm == null) {
+            return false;
+        }
+        if (dm.bitDepth != bitDepth) {
+            return false;
+        }
+        if (dm.refreshRate != refreshRate) {
+            return false;
+        }
+        if (dm.width != width) {
+            return false;
+        }
+        if (dm.height != height) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Gets the bit depth of the DisplayMode, returns BIT_DEPTH_MULTI value
+     * if multiple bit depths are supported in this display mode.
+     * 
+     * @return the bit depth of the DisplayMode.
+     */
+    public int getBitDepth() {
+        return bitDepth;
+    }
+
+    /**
+     * Gets the height of the DisplayMode.
+     * 
+     * @return the height of the DisplayMode.
+     */
+    public int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the refresh rate of the DisplayMode, returns REFRESH_RATE_UNKNOWN
+     * value if the information is not available.
+     * 
+     * @return the refresh rate of the DisplayMode.
+     */
+    public int getRefreshRate() {
+        return refreshRate;
+    }
+
+    /**
+     * Gets the width of the DisplayMode.
+     * 
+     * @return the width of the DisplayMode.
+     */
+    public int getWidth() {
+        return width;
+    }
+}
diff --git a/awt/java/awt/Event.java b/awt/java/awt/Event.java
new file mode 100644
index 0000000..f074258
--- /dev/null
+++ b/awt/java/awt/Event.java
@@ -0,0 +1,479 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.Serializable;
+
+/**
+ * The Event Class is obsolete and has been replaced by AWTEvent class.
+ * 
+ */
+public class Event implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 5488922509400504703L;
+    
+    /** 
+     * The Constant SHIFT_MASK indicates that the Shift key is down when 
+     * the event occurred.
+     */
+    public static final int SHIFT_MASK = 1;
+
+    /** 
+     * The Constant CTRL_MASK indicates that the Control key is down when 
+     * the event occurred.
+     */
+    public static final int CTRL_MASK = 2;
+
+    /** The Constant META_MASK indicates that the Meta key is down when t
+     * he event occurred (or the right mouse button). */
+    public static final int META_MASK = 4;
+
+    /** 
+     * The Constant ALT_MASK indicates that the Alt key is down when 
+     * the event occurred (or the middle mouse button). 
+     */
+    public static final int ALT_MASK = 8;
+
+    /** The Constant HOME indicates Home key. */
+    public static final int HOME = 1000;
+
+    /** The Constant END indicates End key. */
+    public static final int END = 1001;
+
+    /** The Constant PGUP indicates Page Up key. */
+    public static final int PGUP = 1002;
+
+    /** The Constant PGDN indicates Page Down key. */
+    public static final int PGDN = 1003;
+
+    /** The Constant UP indicates Up key. */
+    public static final int UP = 1004;
+
+    /** The Constant DOWN indicates Down key. */
+    public static final int DOWN = 1005;
+
+    /** The Constant LEFT indicates Left key. */
+    public static final int LEFT = 1006;
+
+    /** The Constant RIGHT indicates Right key. */
+    public static final int RIGHT = 1007;
+
+    /** The Constant F1 indicates F1 key. */
+    public static final int F1 = 1008;
+
+    /** The Constant F2 indicates F2 key. */
+    public static final int F2 = 1009;
+
+    /** The Constant F3 indicates F3 key. */
+    public static final int F3 = 1010;
+
+    /** The Constant F4 indicates F4 key. */
+    public static final int F4 = 1011;
+
+    /** The Constant F5 indicates F5 key. */
+    public static final int F5 = 1012;
+
+    /** The Constant F6 indicates F6 key. */
+    public static final int F6 = 1013;
+
+    /** The Constant F7 indicates F7 key. */
+    public static final int F7 = 1014;
+
+    /** The Constant F8 indicates F8 key. */
+    public static final int F8 = 1015;
+
+    /** The Constant F9 indicates F9 key. */
+    public static final int F9 = 1016;
+
+    /** The Constant F10 indicates F10 key. */
+    public static final int F10 = 1017;
+
+    /** The Constant F11 indicates F11 key. */
+    public static final int F11 = 1018;
+
+    /** The Constant F12 indicates F12 key. */
+    public static final int F12 = 1019;
+
+    /** The Constant PRINT_SCREEN  indicates Print Screen key. */
+    public static final int PRINT_SCREEN = 1020;
+
+    /** The Constant SCROLL_LOCK indicates Scroll Lock key. */
+    public static final int SCROLL_LOCK = 1021;
+
+    /** The Constant CAPS_LOCK indicates Caps Lock key. */
+    public static final int CAPS_LOCK = 1022;
+
+    /** The Constant NUM_LOCK indicates Num Lock key. */
+    public static final int NUM_LOCK = 1023;
+
+    /** The Constant PAUSE indicates Pause key. */
+    public static final int PAUSE = 1024;
+
+    /** The Constant INSERT indicates Insert key. */
+    public static final int INSERT = 1025;
+
+    /** The Constant ENTER indicates Enter key. */
+    public static final int ENTER = 10;
+
+    /** The Constant BACK_SPACE indicates Back Space key. */
+    public static final int BACK_SPACE = 8;
+
+    /** The Constant TAB indicates TAb key. */
+    public static final int TAB = 9;
+
+    /** The Constant ESCAPE indicates Escape key. */
+    public static final int ESCAPE = 27;
+
+    /** The Constant DELETE indicates Delete key. */
+    public static final int DELETE = 127;
+
+    /** 
+     * The Constant WINDOW_DESTROY indicates an event when the user has asked the
+     * window manager to kill the window.
+     */
+    public static final int WINDOW_DESTROY = 201;
+
+    /** 
+     * The Constant WINDOW_EXPOSE indicates an event when the user has asked the
+     * window manager to expose the window.
+     */
+    public static final int WINDOW_EXPOSE = 202;
+
+    /** 
+     * The Constant WINDOW_ICONIFY indicates an event when the user has asked the
+     * window manager to inconify the window.
+     */
+    public static final int WINDOW_ICONIFY = 203;
+
+    /** 
+     * The Constant WINDOW_DEICONIFY indicates an event when the user has asked the
+     * window manager to deinconify the window. 
+     */
+    public static final int WINDOW_DEICONIFY = 204;
+
+    /** 
+     * The Constant WINDOW_MOVED indicates an event when the user has asked the
+     * window manager to move the window. 
+     */
+    public static final int WINDOW_MOVED = 205;
+
+    /** 
+     * The Constant KEY_PRESS indicates an event when the user presses 
+     * a normal key. 
+     */
+    public static final int KEY_PRESS = 401;
+
+    /** 
+     * The Constant KEY_RELEASE indicates an event when the user releases 
+     * a normal key.
+     */
+    public static final int KEY_RELEASE = 402;
+
+    /** 
+     * The Constant KEY_ACTION indicates an event when the user pressed 
+     * a non-ASCII action key. 
+     */
+    public static final int KEY_ACTION = 403;
+
+    /**
+     * The Constant KEY_ACTION_RELEASE indicates an event when the user released 
+     * a non-ASCII action key. 
+     */
+    public static final int KEY_ACTION_RELEASE = 404;
+
+    /** 
+     * The Constant MOUSE_DOWN indicates an event when the user has pressed 
+     * the mouse button. 
+     */
+    public static final int MOUSE_DOWN = 501;
+
+    /** 
+     * The Constant MOUSE_UP indicates an event when the user has released 
+     * the mouse button. 
+     */
+    public static final int MOUSE_UP = 502;
+
+    /** 
+     * The Constant MOUSE_MOVE indicates an event when the user has moved
+     * the mouse with no button pressed.
+     */
+    public static final int MOUSE_MOVE = 503;
+
+    /** 
+     * The Constant MOUSE_ENTER indicates an event when the mouse
+     * has entered a component.
+     */
+    public static final int MOUSE_ENTER = 504;
+
+    /** 
+     * The Constant MOUSE_EXIT indicates an event when the mouse
+     * has exited a component. 
+     */
+    public static final int MOUSE_EXIT = 505;
+
+    /** The Constant MOUSE_DRAG indicates an event when the user
+     * has moved a mouse with the pressed button. 
+     */
+    public static final int MOUSE_DRAG = 506;
+
+    /** 
+     * The Constant SCROLL_LINE_UP indicates an event when the user has
+     * activated line-up area of scrollbar.
+     */
+    public static final int SCROLL_LINE_UP = 601;
+
+    /**
+     * The Constant SCROLL_LINE_DOWN indicates an event when the user has
+     * activated line-down area of scrollbar. 
+     */
+    public static final int SCROLL_LINE_DOWN = 602;
+
+    /**
+     * The Constant SCROLL_PAGE_UP indicates an event when the user has
+     * activated page up area of scrollbar. 
+     */
+    public static final int SCROLL_PAGE_UP = 603;
+
+    /**
+     * The Constant SCROLL_PAGE_DOWN indicates an event when the user has
+     * activated page down area of scrollbar. 
+     */
+    public static final int SCROLL_PAGE_DOWN = 604;
+
+    /**
+     * The Constant SCROLL_ABSOLUTE indicates an event when the user 
+     * has moved the bubble in a scroll bar. 
+     */
+    public static final int SCROLL_ABSOLUTE = 605;
+
+    /** The Constant SCROLL_BEGIN indicates a scroll begin event. */
+    public static final int SCROLL_BEGIN = 606;
+
+    /** The Constant SCROLL_END indicates a scroll end event. */
+    public static final int SCROLL_END = 607;
+
+    /** 
+     * The Constant LIST_SELECT indicates that an item in a list 
+     * has been selected.
+     */
+    public static final int LIST_SELECT = 701;
+
+    /** 
+     * The Constant LIST_DESELECT indicates that an item in a list 
+     * has been deselected. 
+     */
+    public static final int LIST_DESELECT = 702;
+
+    /** 
+     * The Constant ACTION_EVENT indicates that the user wants some 
+     * action to occur.
+     */
+    public static final int ACTION_EVENT = 1001;
+
+    /** The Constant LOAD_FILE indicates a file loading event. */
+    public static final int LOAD_FILE = 1002;
+
+    /** The Constant SAVE_FILE indicates a file saving event. */
+    public static final int SAVE_FILE = 1003;
+
+    /** The Constant GOT_FOCUS indicates that a component got the focus. */
+    public static final int GOT_FOCUS = 1004;
+
+    /** The Constant LOST_FOCUS indicates that the component lost the focus. */
+    public static final int LOST_FOCUS = 1005;
+
+    /** The target is the component with which the event is associated. */
+    public Object target;
+
+    /** The when is timestamp when event has occured. */
+    public long when;
+
+    /** The id indicates the type of the event. */
+    public int id;
+
+    /** The x coordinate of event. */
+    public int x;
+
+    /** The y coordinate of event. */
+    public int y;
+
+    /** The key code of key event. */
+    public int key;
+
+    /** The state of the modifier keys (given by a bitmask). */
+    public int modifiers;
+
+    /** The click count indicates the number of consecutive clicks. */
+    public int clickCount;
+
+    /** The argument of the event. */
+    public Object arg;
+
+    /** The next event. */
+    public Event evt;
+
+    /**
+     * Instantiates a new event with the specified target component, 
+     * event type, and argument.
+     * 
+     * @param target the target component.
+     * @param id the event type.
+     * @param arg the argument.
+     */
+    public Event(Object target, int id, Object arg) {
+        this(target, 0l, id, 0, 0, 0, 0, arg);
+    }
+
+    /**
+     * Instantiates a new event with the specified target component, time stamp,
+     * event type, x and y coordinates, keyboard key, state of the modifier
+     * keys, and an argument set to null.
+     * 
+     * @param target the target component.
+     * @param when the time stamp.
+     * @param id the event type.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param key the key.
+     * @param modifiers the modifier keys state.
+     */
+    public Event(Object target, long when, int id, int x, int y, int key, int modifiers) {
+        this(target, when, id, x, y, key, modifiers, null);
+    }
+
+    /**
+     * Instantiates a new event with the specified target component, time stamp,
+     * event type, x and y coordinates, keyboard key, state of the modifier
+     * keys, and an argument.
+     * 
+     * @param target the target component.
+     * @param when the time stamp.
+     * @param id the event type.
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param key the key.
+     * @param modifiers the modifier keys state.
+     * @param arg the specified argument.
+     */
+    public Event(Object target, long when, int id, int x, int y, int key, int modifiers, Object arg) {
+        this.target = target;
+        this.when = when;
+        this.id = id;
+        this.x = x;
+        this.y = y;
+        this.key = key;
+        this.modifiers = modifiers;
+        this.arg = arg;
+    }
+
+    /**
+     * Returns a string representation of this Event.
+     * 
+     * @return a string representation of this Event.
+     */
+    @Override
+    public String toString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * Event e = new Event(new Button(), 0l, Event.KEY_PRESS, 
+         *                     0, 0, Event.TAB, Event.SHIFT_MASK, "arg");
+         * System.out.println(e);
+         */
+
+        return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Returns a string representing the state of this Event.
+     * 
+     * @return a string representing the state of this Event.
+     */
+    protected String paramString() {
+        return "id=" + id + ",x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        (key != 0 ? ",key=" + key  + getModifiersString() : "") + //$NON-NLS-1$ //$NON-NLS-2$
+        ",target=" + target + //$NON-NLS-1$
+        (arg != null ? ",arg=" + arg : ""); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets a string representation of the modifiers.
+     * 
+     * @return a string representation of the modifiers
+     */
+    private String getModifiersString() {
+        String strMod = ""; //$NON-NLS-1$
+        if (shiftDown()) {
+            strMod += ",shift"; //$NON-NLS-1$
+        }
+        if (controlDown()) {
+            strMod += ",control"; //$NON-NLS-1$
+        }
+        if (metaDown()) {
+            strMod += ",meta"; //$NON-NLS-1$
+        }
+        return strMod;
+    }
+
+    /**
+     * Translates x and y coordinates of his event to the x+dx and x+dy 
+     * coordinates.
+     * 
+     * @param dx the dx - the distance by which the event's x coordinate
+     * is increased 
+     * @param dy the dy - the distance by which the event's y coordinate
+     * is increased 
+     */
+    public void translate(int dx, int dy) {
+        x += dx;
+        y += dy;
+    }
+
+    /**
+     * Checks if Control key is down or not.
+     * 
+     * @return true, if Control key is down; false otherwise.
+     */
+    public boolean controlDown() {
+        return (modifiers & CTRL_MASK) != 0;
+    }
+
+    /**
+     * Checks if Meta key is down or not.
+     * 
+     * @return true, if Meta key is down; false otherwise.
+     */
+    public boolean metaDown() {
+        return (modifiers & META_MASK) != 0;
+    }
+
+    /**
+     * Checks if Shift key is down or not.
+     * 
+     * @return true, if Shift key is down; false otherwise.
+     */
+    public boolean shiftDown() {
+        return (modifiers & SHIFT_MASK) != 0;
+    }
+
+}
+
diff --git a/awt/java/awt/EventDispatchThread.java b/awt/java/awt/EventDispatchThread.java
new file mode 100644
index 0000000..442c8a2
--- /dev/null
+++ b/awt/java/awt/EventDispatchThread.java
@@ -0,0 +1,118 @@
+/*
+ *  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 Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import org.apache.harmony.awt.wtk.NativeEvent;
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+
+class EventDispatchThread extends Thread  {
+    
+    private static final class MarkerEvent extends AWTEvent {
+        MarkerEvent(Object source, int id) {
+            super(source, id);
+        }
+    }
+
+    final Dispatcher dispatcher;
+    final Toolkit toolkit;
+    private NativeEventQueue nativeQueue;
+
+    protected volatile boolean shutdownPending = false;
+
+    /**
+     * Initialise and run the main event loop
+     */
+    @Override
+    public void run() {
+        nativeQueue = toolkit.getNativeEventQueue();
+
+        try {
+            runModalLoop(null);
+        } finally {
+            toolkit.shutdownWatchdog.forceShutdown();
+        }
+    }
+
+    void runModalLoop(ModalContext context) {
+        long lastPaintTime = System.currentTimeMillis();
+        while (!shutdownPending && (context == null || context.isModalLoopRunning())) {
+            try {
+            EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
+
+            NativeEvent ne = nativeQueue.getNextEvent();
+            if (ne != null) {
+                dispatcher.onEvent(ne);
+                MarkerEvent marker = new MarkerEvent(this, 0);
+                eventQueue.postEvent(marker);
+                for (AWTEvent ae = eventQueue.getNextEventNoWait(); 
+                        (ae != null) && (ae != marker); 
+                        ae = eventQueue.getNextEventNoWait()) {
+                    eventQueue.dispatchEvent(ae);
+                }
+            } else {
+                toolkit.shutdownWatchdog.setNativeQueueEmpty(true);
+                AWTEvent ae = eventQueue.getNextEventNoWait();
+                if (ae != null) {
+                    eventQueue.dispatchEvent(ae);
+                    long curTime = System.currentTimeMillis();
+                    if (curTime - lastPaintTime > 10) {
+                        toolkit.onQueueEmpty();
+                        lastPaintTime = System.currentTimeMillis();
+                    }
+                } else {
+                    toolkit.shutdownWatchdog.setAwtQueueEmpty(true);
+                    toolkit.onQueueEmpty();
+                    lastPaintTime = System.currentTimeMillis();
+                    waitForAnyEvent();
+                }
+            }
+            } catch (Throwable t) {
+                // TODO: Exception handler should be implemented
+                // t.printStackTrace();
+            }
+        }
+    }
+    
+    private void waitForAnyEvent() {
+        EventQueue eventQueue = toolkit.getSystemEventQueueImpl();
+        if (!eventQueue.isEmpty() || !nativeQueue.isEmpty()) {
+            return;
+        }
+        Object eventMonitor = nativeQueue.getEventMonitor();
+        synchronized(eventMonitor) {
+            try {
+                eventMonitor.wait();
+            } catch (InterruptedException e) {}
+        }
+    }
+
+    void shutdown() {
+        shutdownPending = true;
+    }
+
+    EventDispatchThread(Toolkit toolkit, Dispatcher dispatcher ) {
+        this.toolkit = toolkit;
+        this.dispatcher = dispatcher;
+        setName("AWT-EventDispatchThread"); //$NON-NLS-1$
+        setDaemon(true);
+    }
+
+}
diff --git a/awt/java/awt/EventQueue.java b/awt/java/awt/EventQueue.java
new file mode 100644
index 0000000..3997546
--- /dev/null
+++ b/awt/java/awt/EventQueue.java
@@ -0,0 +1,310 @@
+/*
+ *  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 Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.InvocationEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.EmptyStackException;
+
+/**
+ * The EventQueue class manages events. It is a platform-independent class 
+ * that queues events both from the underlying peer classes and from trusted 
+ * application classes.
+ */
+public class EventQueue {
+    
+    /** The core ref. */
+    private final EventQueueCoreAtomicReference coreRef = 
+            new EventQueueCoreAtomicReference();
+    
+    /**
+     * The Class EventQueueCoreAtomicReference.
+     */
+    private static final class EventQueueCoreAtomicReference {
+        
+        /** The core. */
+        private EventQueueCore core;
+
+        /*synchronized*/ /**
+         * Gets the.
+         * 
+         * @return the event queue core
+         */
+        EventQueueCore get() { 
+            return core;
+        }
+
+        /*synchronized*/ /**
+         * Sets the.
+         * 
+         * @param newCore the new core
+         */
+        void set(EventQueueCore newCore) { 
+            core = newCore;
+        }
+    }
+
+    /**
+     * Returns true if the calling thread is the current 
+     * AWT EventQueue's dispatch thread. 
+     * 
+     * @return true, if the calling thread is the current 
+     * AWT EventQueue's dispatch thread; false otherwise.
+     */
+    public static boolean isDispatchThread() {
+        return Thread.currentThread() instanceof EventDispatchThread;
+    }
+
+    /**
+     * Posts an InvocationEvent which executes the run() method on a Runnable 
+     * when dispatched by the AWT event dispatcher thread.
+     * 
+     * @param runnable the Runnable whose run method should be executed 
+     * synchronously on the EventQueue.
+     */
+    public static void invokeLater(Runnable runnable) {
+        Toolkit toolkit = Toolkit.getDefaultToolkit();
+        InvocationEvent event = new InvocationEvent(toolkit, runnable);
+        toolkit.getSystemEventQueueImpl().postEvent(event);
+    }
+
+    /**
+     * Posts an InvocationEvent which executes the run() method on a Runnable 
+     * when dispatched by the AWT event dispatcher thread and the 
+     * notifyAll method is called on it immediately after run returns.
+     * 
+     * @param runnable the Runnable whose run method should be executed 
+     * synchronously on the EventQueue.
+     * 
+     * @throws InterruptedException if another thread has interrupted 
+     * this thread.
+     * @throws InvocationTargetException if a throwable is thrown 
+     * when running the runnable. 
+     */
+    public static void invokeAndWait(Runnable runnable)
+            throws InterruptedException, InvocationTargetException {
+
+        if (isDispatchThread()) {
+            throw new Error();
+        }
+
+        final Toolkit toolkit = Toolkit.getDefaultToolkit();
+        final Object notifier = new Object();  //$NON-LOCK-1$
+        InvocationEvent event = new InvocationEvent(
+                toolkit, runnable, notifier, true);
+
+        synchronized (notifier) {
+            toolkit.getSystemEventQueueImpl().postEvent(event);
+            notifier.wait();
+        }
+
+        Exception exception = event.getException();
+
+        if (exception != null) {
+            throw new InvocationTargetException(exception);
+        }
+    }
+
+    /**
+     * Gets the system event queue.
+     * 
+     * @return the system event queue
+     */
+    private static EventQueue getSystemEventQueue() {
+        Thread th = Thread.currentThread();
+        if (th instanceof EventDispatchThread) {
+            return ((EventDispatchThread)th).toolkit.getSystemEventQueueImpl();
+        }
+        return null;
+    }
+    
+    /**
+     * Gets the most recent event's timestamp.
+     * This event was dispatched from the EventQueue associated with the 
+     * calling thread.
+     * 
+     * @return the timestamp of the last Event to be dispatched, 
+     * or System.currentTimeMillis() if this method is invoked from 
+     * a thread other than an event-dispatching thread.
+     */
+    public static long getMostRecentEventTime() {
+        EventQueue eq = getSystemEventQueue();
+        return (eq != null) ? 
+                eq.getMostRecentEventTimeImpl() : System.currentTimeMillis();
+    }
+    
+    /**
+     * Gets the most recent event time impl.
+     * 
+     * @return the most recent event time impl
+     */
+    private long getMostRecentEventTimeImpl() {
+        return getCore().getMostRecentEventTime();
+    }
+
+    /**
+     * Returns the the currently dispatched event by the EventQueue 
+     * associated with the calling thread.
+     * 
+     * @return the currently dispatched event or null if this method 
+     * is invoked from a thread other than an event-dispatching thread.
+     */
+    public static AWTEvent getCurrentEvent() {
+        EventQueue eq = getSystemEventQueue();
+        return (eq != null) ? 
+                eq.getCurrentEventImpl() : null;
+    }
+
+    /**
+     * Gets the current event impl.
+     * 
+     * @return the current event impl
+     */
+    private AWTEvent getCurrentEventImpl() {
+        return getCore().getCurrentEvent();
+    }
+
+    /**
+     * Instantiates a new event queue.
+     */
+    public EventQueue() {
+        setCore(new EventQueueCore(this));
+    }
+
+    /**
+     * Instantiates a new event queue.
+     * 
+     * @param t the t
+     */
+    EventQueue(Toolkit t) {
+        setCore(new EventQueueCore(this, t));
+    }
+
+    /**
+     * Posts a event to the EventQueue.
+     * 
+     * @param event AWTEvent.
+     */
+    public void postEvent(AWTEvent event) {
+        event.isPosted = true;
+        getCore().postEvent(event);
+    }
+
+    /**
+     * Returns an event from the EventQueue and removes it from this queue. 
+     *  
+     * @return the next AWTEvent.
+     * 
+     * @throws InterruptedException is thrown if another thread 
+     * interrupts this thread.
+     */
+    public AWTEvent getNextEvent() throws InterruptedException {
+        return getCore().getNextEvent();
+    }
+    
+    /**
+     * Gets the next event no wait.
+     * 
+     * @return the next event no wait
+     */
+    AWTEvent getNextEventNoWait() {
+        return getCore().getNextEventNoWait();
+    }
+
+    /**
+     * Returns the first event of the EventQueue (without removing it 
+     * from the queue).
+     * 
+     * @return the the first AWT event of the EventQueue.
+     */
+    public AWTEvent peekEvent() {
+        return getCore().peekEvent();
+    }
+
+    /**
+     * Returns the first event of the EventQueue with the specified ID
+     * (without removing it from the queue).
+     * 
+     * @param id the type ID of event.
+     * 
+     * @return the first event of the EventQueue with the specified ID.
+     */
+    public AWTEvent peekEvent(int id) {
+        return getCore().peekEvent(id);
+    }
+
+    /**
+     * Replaces the existing EventQueue with the specified EventQueue. 
+     * Any pending events are transferred to the new EventQueue. 
+     * 
+     * @param newEventQueue the new event queue.
+     */
+    public void push(EventQueue newEventQueue) {
+        getCore().push(newEventQueue);
+    }
+    
+    /**
+     * Stops dispatching events using this EventQueue. 
+     * Any pending events are transferred to the previous EventQueue.
+     * 
+     * @throws EmptyStackException is thrown if no previous push 
+     * was made on this EventQueue.
+     */
+    protected void pop() throws EmptyStackException {
+        getCore().pop();
+    }
+
+    /**
+     * Dispatches the specified event.
+     * 
+     * @param event the AWTEvent.
+     */
+    protected void dispatchEvent(AWTEvent event) {
+        getCore().dispatchEventImpl(event);
+    }
+
+    /**
+     * Checks if the queue is empty.
+     * 
+     * @return true, if is empty
+     */
+    boolean isEmpty() {
+        return getCore().isEmpty();
+    }
+
+    /**
+     * Gets the core.
+     * 
+     * @return the core
+     */
+    EventQueueCore getCore() {
+        return coreRef.get();
+    }
+    
+    /**
+     * Sets the core.
+     * 
+     * @param newCore the new core
+     */
+    void setCore(EventQueueCore newCore) {
+        coreRef.set((newCore != null) ? newCore : new EventQueueCore(this));
+    }
+}
diff --git a/awt/java/awt/EventQueueCore.java b/awt/java/awt/EventQueueCore.java
new file mode 100644
index 0000000..ffc7c46
--- /dev/null
+++ b/awt/java/awt/EventQueueCore.java
@@ -0,0 +1,253 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.InvocationEvent;
+import java.awt.event.MouseEvent;
+import java.util.LinkedList;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The events storage for EventQueue
+ */
+final class EventQueueCore {
+    
+    private final LinkedList<EventQueue> queueStack = new LinkedList<EventQueue>();
+    private final LinkedList<AWTEvent> events = new LinkedList<AWTEvent>();
+    
+    private Toolkit toolkit;
+    private EventQueue activeQueue;
+    private Thread dispatchThread;
+    
+    AWTEvent currentEvent;
+    long mostRecentEventTime = System.currentTimeMillis();
+    
+    EventQueueCore(EventQueue eq) {
+        synchronized (this) {
+            queueStack.addLast(eq);
+            activeQueue = eq;
+        }
+    }
+
+    EventQueueCore(EventQueue eq, Toolkit t) {
+        synchronized (this) {
+            queueStack.addLast(eq);
+            activeQueue = eq;
+            setToolkit(t);
+        }
+    }
+
+    synchronized long getMostRecentEventTime() {
+        return mostRecentEventTime;
+    }
+    
+    synchronized AWTEvent getCurrentEvent() {
+        return currentEvent;
+    }
+    
+    synchronized boolean isSystemEventQueue() {
+        return toolkit != null;
+    }
+    
+    private void setToolkit(Toolkit t) {
+        toolkit = t;
+        if (toolkit != null) {
+            toolkit.setSystemEventQueueCore(this);
+            dispatchThread = toolkit.dispatchThread;
+        }
+    }
+
+    synchronized void postEvent(AWTEvent event) {
+        //???AWT
+        /*
+        events.addLast(event);
+        if ((toolkit == null) && (dispatchThread == null)) {
+            dispatchThread = new EventQueueThread(this);
+            dispatchThread.start();
+        }
+        // TODO: add event coalescing
+        if (toolkit != null) {
+            toolkit.shutdownWatchdog.setAwtQueueEmpty(false);
+            if (!GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance()) {
+                notifyEventMonitor(toolkit);
+            }
+        }
+        notifyAll();
+        */
+    }
+    
+    void notifyEventMonitor(Toolkit t) {
+        Object em = t.getNativeEventQueue().getEventMonitor();
+        synchronized (em) {
+            em.notifyAll();
+        }
+    }
+    
+    synchronized AWTEvent getNextEvent() throws InterruptedException {
+        while (events.isEmpty()) {
+            wait();
+        }
+        AWTEvent event = events.removeFirst();
+        // TODO: add event coalescing
+        return event;
+    }    
+    
+    synchronized AWTEvent peekEvent() {
+        return events.isEmpty() ? null : events.getFirst();
+    }
+    
+    synchronized AWTEvent peekEvent(int id) {
+        for (AWTEvent event : events) {
+            if (event.getID() == id) {
+                return event;
+            }
+        }
+        return null;
+    }
+    
+    synchronized void dispatchEvent(AWTEvent event) {
+        updateCurrentEventAndTime(event);
+        try {
+            activeQueue.dispatchEvent(event);
+        } finally {
+            currentEvent = null;
+        }
+    }
+    
+    void dispatchEventImpl(AWTEvent event) {
+        if (event instanceof ActiveEvent) {
+            updateCurrentEventAndTime(event);
+            try {
+                ((ActiveEvent) event).dispatch();
+            } finally {
+                currentEvent = null;
+            }
+            return;
+        }
+
+        Object src = event.getSource();
+
+        if (src instanceof Component) {
+            if (preprocessComponentEvent(event)) {
+                ((Component) src).dispatchEvent(event);
+            }
+        } else {
+            if (toolkit != null) {
+                toolkit.dispatchAWTEvent(event);
+            }
+            if (src instanceof MenuComponent) {
+                ((MenuComponent) src).dispatchEvent(event);
+            }
+        }
+    }
+
+    private final boolean preprocessComponentEvent(AWTEvent event) {
+      if (event instanceof MouseEvent) {
+          return preprocessMouseEvent((MouseEvent)event);
+      }
+      return true;
+    }
+
+    private final boolean preprocessMouseEvent(MouseEvent event) {
+        //???AWT
+        /*
+      if (toolkit != null && toolkit.mouseEventPreprocessor != null) {
+          toolkit.lockAWT();
+          try {
+              return toolkit.mouseEventPreprocessor.preprocess(event);
+          } finally {
+              toolkit.unlockAWT();
+          }
+      }
+      return true;
+        */
+        return true;
+    }
+    
+    private void updateCurrentEventAndTime(AWTEvent event) {
+        currentEvent = event;
+        long when = 0;
+        if (event instanceof ActionEvent) {
+            when = ((ActionEvent) event).getWhen();
+        } else if (event instanceof InputEvent) {
+            when = ((InputEvent) event).getWhen();
+        } else if (event instanceof InputMethodEvent) {
+            when = ((InputMethodEvent) event).getWhen();
+        } else if (event instanceof InvocationEvent) {
+            when = ((InvocationEvent) event).getWhen();
+        }
+        if (when != 0) {
+            mostRecentEventTime = when;
+        }
+    }
+    
+    synchronized void push(EventQueue newEventQueue) {
+        // TODO: handle incorrect situations
+        if (queueStack.isEmpty()) {
+            // awt.6B=Queue stack is empty
+            throw new IllegalStateException(Messages.getString("awt.6B")); //$NON-NLS-1$
+        }
+        
+        queueStack.addLast(newEventQueue);
+        activeQueue = newEventQueue;
+        activeQueue.setCore(this);
+    }
+    
+    synchronized void pop() {
+        EventQueue removed = queueStack.removeLast();
+        if (removed != activeQueue) {
+            // awt.6C=Event queue stack is broken
+            throw new IllegalStateException(Messages.getString("awt.6C")); //$NON-NLS-1$
+        }
+        activeQueue = queueStack.getLast();
+        removed.setCore(null);
+    }
+
+    synchronized AWTEvent getNextEventNoWait() {
+        try {
+            return events.isEmpty() ? null : activeQueue.getNextEvent();
+        } catch (InterruptedException e) {
+            return null;
+        }
+    }
+
+    synchronized boolean isEmpty() {
+        return (currentEvent == null) && events.isEmpty();
+    }
+    
+    synchronized boolean isEmpty(long timeout) {
+        if (!isEmpty()) {
+            return false;
+        }
+        try {
+            wait(timeout);
+        } catch (InterruptedException e) {}
+        return isEmpty();
+    }
+    
+    synchronized EventQueue getActiveEventQueue() {
+        return activeQueue;
+    }
+}
diff --git a/awt/java/awt/Font.java b/awt/java/awt/Font.java
new file mode 100644
index 0000000..139ae68
--- /dev/null
+++ b/awt/java/awt/Font.java
@@ -0,0 +1,1500 @@
+/*
+ *  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 java.awt;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineMetrics;
+import java.awt.font.TextAttribute;
+import java.awt.font.TransformAttribute;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.text.CharacterIterator;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.gl.font.AndroidGlyphVector;
+import org.apache.harmony.awt.gl.font.CommonGlyphVector;
+import org.apache.harmony.awt.gl.font.FontPeerImpl;
+import org.apache.harmony.awt.gl.font.FontMetricsImpl;
+import org.apache.harmony.awt.gl.font.LineMetricsImpl;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The Font class represents fonts for rendering text. 
+ * This class allow to map characters to glyphs.
+ * <p> 
+ * A glyph is a shape used to render a character or a sequence of 
+ * characters. For example one character of Latin writing system 
+ * represented by one glyth, but in complex writing system such as 
+ * South and South-East Asian there is more complicated correspondence 
+ * between characters and glyphs.
+ * <p>
+ * The Font object is identified by two types of names. The logical font name 
+ * is the name that is used to construct the font. The font name
+ * is the name of a particular font face (for example, Arial Bold). 
+ * The family name is the font's family name that specifies 
+ * the typographic design across several faces (for example, Arial). In 
+ * all the Font is identified by three attributes: the family name, 
+ * the style (such as bold or italic), and the size.
+ */
+public class Font implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4206021311591459213L;
+
+    // Identity Transform attribute
+    /** The Constant IDENTITY_TRANSFORM. */
+    private static final TransformAttribute IDENTITY_TRANSFORM = new TransformAttribute(
+            new AffineTransform());
+
+    /** The Constant PLAIN indicates font's plain style. */
+    public static final int PLAIN = 0;
+
+    /** The Constant BOLD indicates font's bold style. */
+    public static final int BOLD = 1;
+
+    /** The Constant ITALIC indicates font's italic style. */
+    public static final int ITALIC = 2;
+
+    /** The Constant ROMAN_BASELINE indicated roman baseline. */
+    public static final int ROMAN_BASELINE = 0;
+
+    /** The Constant CENTER_BASELINE indicates center baseline. */
+    public static final int CENTER_BASELINE = 1;
+
+    /** The Constant HANGING_BASELINE indicates hanging baseline. */
+    public static final int HANGING_BASELINE = 2;
+
+    /** 
+     * The Constant TRUETYPE_FONT indicates a font resource of 
+     * type TRUETYPE. 
+     */
+    public static final int TRUETYPE_FONT = 0;
+
+    /** 
+     * The Constant TYPE1_FONT indicates a font resource of
+     * type TYPE1. 
+     */
+    public static final int TYPE1_FONT = 1;
+
+    /** 
+     * The Constant LAYOUT_LEFT_TO_RIGHT indicates that text is
+     * left to right. 
+     */
+    public static final int LAYOUT_LEFT_TO_RIGHT = 0;
+
+    /** 
+     * The Constant LAYOUT_RIGHT_TO_LEFT indicates that text is
+     * right to left. 
+     */
+    public static final int LAYOUT_RIGHT_TO_LEFT = 1;
+
+    /** 
+     * The Constant LAYOUT_NO_START_CONTEXT indicates that the text
+     * in the char array before the indicated start should not be examined. 
+     */
+    public static final int LAYOUT_NO_START_CONTEXT = 2;
+
+    /** The Constant LAYOUT_NO_LIMIT_CONTEXT indicates that text in 
+     * the char array after the indicated limit should not be examined. */
+    public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;
+
+    /** The Constant DEFAULT_FONT. */
+    static final Font DEFAULT_FONT = new Font("Dialog", Font.PLAIN, 12); //$NON-NLS-1$
+
+    /** The name of the Font. */
+    protected String name;
+
+    /** The style of the Font. */
+    protected int style;
+
+    /** The size of the Font. */
+    protected int size;
+
+    /** The point size of the Font. */
+    protected float pointSize;
+
+    // Flag if the Font object transformed
+    /** The transformed. */
+    private boolean transformed;
+
+    // Set of font attributes
+    /** The requested attributes. */
+    private Hashtable<Attribute, Object> fRequestedAttributes;
+
+    // font peer object corresponding to this Font
+    /** The font peer. */
+    private transient FontPeerImpl fontPeer;
+
+    // number of glyphs in this Font
+    /** The num glyphs. */
+    private transient int numGlyphs = -1;
+
+    // code for missing glyph for this Font
+    /** The missing glyph code. */
+    private transient int missingGlyphCode = -1;
+
+    /**
+     * Writes object to ObjectOutputStream.
+     * 
+     * @param out ObjectOutputStream
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+    }
+
+    /**
+     * Reads object from ObjectInputStream object and set native platform
+     * dependent fields to default values.
+     * 
+     * @param in ObjectInputStream object
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException the class not found exception
+     */
+    private void readObject(java.io.ObjectInputStream in) throws IOException,
+            ClassNotFoundException {
+        in.defaultReadObject();
+
+        numGlyphs = -1;
+        missingGlyphCode = -1;
+
+    }
+
+    /**
+     * Instantiates a new Font with the specified attributes. 
+     * The Font will be created with default attributes 
+     * if the attribute's parameter is null. 
+     * 
+     * @param attributes the attributes to be assigned to the new Font, or null.
+     */
+    public Font(Map<? extends Attribute, ?> attributes) {
+        Object currAttr;
+
+        // Default values are taken from the documentation of the Font class.
+        // See Font constructor, decode and getFont sections.
+
+        this.name = "default"; //$NON-NLS-1$
+        this.size = 12;
+        this.pointSize = 12;
+        this.style = Font.PLAIN;
+
+        if (attributes != null) {
+
+            fRequestedAttributes = new Hashtable<Attribute, Object>(attributes);
+
+            currAttr = attributes.get(TextAttribute.SIZE);
+            if (currAttr != null) {
+                this.pointSize = ((Float) currAttr).floatValue();
+                this.size = (int) Math.ceil(this.pointSize);
+            }
+
+            currAttr = attributes.get(TextAttribute.POSTURE);
+            if (currAttr != null
+                    && currAttr.equals(TextAttribute.POSTURE_OBLIQUE)) {
+                this.style |= Font.ITALIC;
+            }
+
+            currAttr = attributes.get(TextAttribute.WEIGHT);
+            if ((currAttr != null)
+                    && (((Float) currAttr).floatValue() >= (TextAttribute.WEIGHT_BOLD)
+                            .floatValue())) {
+                this.style |= Font.BOLD;
+            }
+
+            currAttr = attributes.get(TextAttribute.FAMILY);
+            if (currAttr != null) {
+                this.name = (String) currAttr;
+            }
+
+            currAttr = attributes.get(TextAttribute.TRANSFORM);
+            if (currAttr != null) {
+                if (currAttr instanceof TransformAttribute) {
+                    this.transformed = !((TransformAttribute) currAttr)
+                            .getTransform().isIdentity();
+                } else if (currAttr instanceof AffineTransform) {
+                    this.transformed = !((AffineTransform) currAttr)
+                            .isIdentity();
+                }
+            }
+
+        } else {
+            fRequestedAttributes = new Hashtable<Attribute, Object>(5);
+            fRequestedAttributes.put(TextAttribute.TRANSFORM,
+                    IDENTITY_TRANSFORM);
+
+            this.transformed = false;
+
+            fRequestedAttributes.put(TextAttribute.FAMILY, name);
+
+            fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
+
+            if ((this.style & Font.BOLD) != 0) {
+                fRequestedAttributes.put(TextAttribute.WEIGHT,
+                        TextAttribute.WEIGHT_BOLD);
+            } else {
+                fRequestedAttributes.put(TextAttribute.WEIGHT,
+                        TextAttribute.WEIGHT_REGULAR);
+            }
+            if ((this.style & Font.ITALIC) != 0) {
+                fRequestedAttributes.put(TextAttribute.POSTURE,
+                        TextAttribute.POSTURE_OBLIQUE);
+            } else {
+                fRequestedAttributes.put(TextAttribute.POSTURE,
+                        TextAttribute.POSTURE_REGULAR);
+            }
+
+        }
+    }
+
+    /**
+     * Instantiates a new Font with the specified name, style and size.
+     * 
+     * @param name the name of font.
+     * @param style the style of font.
+     * @param size the size of font.
+     */
+    public Font(String name, int style, int size) {
+
+        this.name = (name != null) ? name : "Default"; //$NON-NLS-1$
+        this.size = (size >= 0) ? size : 0;
+        this.style = (style & ~0x03) == 0 ? style : Font.PLAIN;
+        this.pointSize = this.size;
+
+        fRequestedAttributes = new Hashtable<Attribute, Object>(5);
+
+        fRequestedAttributes.put(TextAttribute.TRANSFORM, IDENTITY_TRANSFORM);
+
+        this.transformed = false;
+
+        fRequestedAttributes.put(TextAttribute.FAMILY, this.name);
+        fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
+
+        if ((this.style & Font.BOLD) != 0) {
+            fRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else {
+            fRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_REGULAR);
+        }
+        if ((this.style & Font.ITALIC) != 0) {
+            fRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else {
+            fRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_REGULAR);
+        }
+    }
+
+    /**
+     * Returns true if this Font has a glyph for the specified character.
+     * 
+     * @param c the character.
+     * 
+     * @return true if this Font has a glyph for the specified character,
+     * false otherwise.
+     */
+    public boolean canDisplay(char c) {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.canDisplay(c);
+    }
+
+    /**
+     * Returns true if the Font can display the characters of the 
+     * the specified text from the specified start position 
+     * to the specified limit position. 
+     * 
+     * @param text the text.
+     * @param start the start offset (in the character array).
+     * @param limit the limit offset (in the character array).
+     * 
+     * @return the a character's position in the text that this Font 
+     * can not display, or -1 if this Font can display all characters 
+     * in this text.
+     */
+    public int canDisplayUpTo(char[] text, int start, int limit) {
+        int st = start;
+        int result;
+        while ((st < limit) && canDisplay(text[st])) {
+            st++;
+        }
+
+        if (st == limit) {
+            result = -1;
+        } else {
+            result = st;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns true if the Font can display the characters of the 
+     * the specified CharacterIterator from the specified start position 
+     * and the specified limit position. 
+     * 
+     * @param iter the CharacterIterator.
+     * @param start the start offset.
+     * @param limit the limit offset.
+     * 
+     * @return the a character's position in the CharacterIterator
+     * that this Font can not display, or -1 if this Font can display 
+     * all characters in this text.
+     */
+    public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
+        int st = start;
+        char c = iter.setIndex(start);
+        int result;
+
+        while ((st < limit) && (canDisplay(c))) {
+            st++;
+            c = iter.next();
+        }
+        if (st == limit) {
+            result = -1;
+        } else {
+            result = st;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns true if this Font can display a specified String.
+     * 
+     * @param str the String.
+     * 
+     * @return the a character's position in the String that 
+     * this Font can not display, or -1 if this Font can display 
+     * all characters in this text.
+     */
+    public int canDisplayUpTo(String str) {
+        char[] chars = str.toCharArray();
+        return canDisplayUpTo(chars, 0, chars.length);
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param chars the characters array.
+     * 
+     * @return the GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, char[] chars) {
+        return new AndroidGlyphVector(chars, frc, this, 0);
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters contained
+     * in the specified CharacterIterator to glyphs based on 
+     * the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param iter the CharacterIterator.
+     * 
+     * @return the GlyphVector of associating characters contained
+     * in the specified CharacterIterator to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc,
+            CharacterIterator iter) {
+    	throw new RuntimeException("Not implemented!"); //$NON-NLS-1$    
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs based on 
+     * the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param glyphCodes the specified integer array of glyph codes.
+     * 
+     * @return the GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, int[] glyphCodes)
+            throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented!"); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates a GlyphVector of associating characters to glyphs based on 
+     * the unicode map of this Font. 
+     * 
+     * @param frc the FontRenderContext.
+     * @param str the specified String.
+     * 
+     * @return the GlyphVector of associating characters to glyphs 
+     * based on the unicode map of this Font.
+     */
+    public GlyphVector createGlyphVector(FontRenderContext frc, String str) {
+        return new AndroidGlyphVector(str.toCharArray(), frc, this, 0);
+
+    }
+
+    /**
+     * Returns the font style constant value corresponding to one of the font style
+     * names ("BOLD", "ITALIC", "BOLDITALIC"). This method returns Font.PLAIN if
+     * the argument is not one of the predefined style names.
+     * 
+     * @param fontStyleName font style name
+     * 
+     * @return font style constant value corresponding to the font style name
+     * specified.
+     */
+    private static int getFontStyle(String fontStyleName) {
+        int result = Font.PLAIN;
+
+        if (fontStyleName.toUpperCase().equals("BOLDITALIC")) { //$NON-NLS-1$
+            result = Font.BOLD | Font.ITALIC;
+        } else if (fontStyleName.toUpperCase().equals("BOLD")) { //$NON-NLS-1$
+            result = Font.BOLD;
+        } else if (fontStyleName.toUpperCase().equals("ITALIC")) { //$NON-NLS-1$
+            result = Font.ITALIC;
+        }
+
+        return result;
+    }
+
+    /**
+     * Decodes the specified string which described the Font. The string 
+     * should have the following format: fontname-style-pointsize. 
+     * The style can be PLAIN, BOLD, BOLDITALIC, or ITALIC.
+     * 
+     * @param str the string which describes the font.
+     * 
+     * @return the Font from the specified string.
+     */
+    public static Font decode(String str) {
+        // XXX: Documentation doesn't describe all cases, e.g. fonts face names
+        // with
+        // symbols that are suggested as delimiters in the documentation.
+        // In this decode implementation only ***-***-*** format is used with
+        // '-'
+        // as the delimiter to avoid unexpected parse results of font face names
+        // with spaces.
+
+        if (str == null) {
+            return DEFAULT_FONT;
+        }
+
+        StringTokenizer strTokens;
+        String delim = "-"; //$NON-NLS-1$
+        String substr;
+
+        int fontSize = DEFAULT_FONT.size;
+        int fontStyle = DEFAULT_FONT.style;
+        String fontName = DEFAULT_FONT.name;
+
+        strTokens = new StringTokenizer(str.trim(), delim);
+
+        // Font Name
+        if (strTokens.hasMoreTokens()) {
+            fontName = strTokens.nextToken(); // first token is the font name
+        }
+
+        // Font Style or Size (if the style is undefined)
+        if (strTokens.hasMoreTokens()) {
+            substr = strTokens.nextToken();
+
+            try {
+                // if second token is the font size
+                fontSize = Integer.parseInt(substr);
+            } catch (NumberFormatException e) {
+                // then second token is the font style
+                fontStyle = getFontStyle(substr);
+            }
+
+        }
+
+        // Font Size
+        if (strTokens.hasMoreTokens()) {
+            try {
+                fontSize = Integer.parseInt(strTokens.nextToken());
+            } catch (NumberFormatException e) {
+            }
+        }
+
+        return new Font(fontName, fontStyle, fontSize);
+    }
+
+    /**
+     * Perfoms the specified affine transform to the Font and returns 
+     * a new Font.
+     * 
+     * @param trans the AffineTransform.
+     * 
+     * @return the Font object.
+     * 
+     * @throws IllegalArgumentException if affine transform parameter
+     * is null.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(AffineTransform trans) {
+
+        if (trans == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        derivefRequestedAttributes.put(TextAttribute.TRANSFORM,
+                new TransformAttribute(trans));
+
+        return new Font(derivefRequestedAttributes);
+
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font 
+     * modified so that the size is the specified size.
+     * 
+     * @param size the size of font.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(float size) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+        derivefRequestedAttributes.put(TextAttribute.SIZE, new Float(size));
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font 
+     * modified so that the style is the specified style.
+     * 
+     * @param style the style of font.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        if ((style & Font.BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & Font.ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font
+     * modified to match the specified style and with the specified
+     * affine transform applied to its glyphs.
+     * 
+     * @param style the style of font.
+     * @param trans the AffineTransform.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style, AffineTransform trans) {
+
+        if (trans == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        if ((style & BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+        derivefRequestedAttributes.put(TextAttribute.TRANSFORM,
+                new TransformAttribute(trans));
+
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Returns a new Font that is a copy of the current Font 
+     * modified so that the size and style are the specified 
+     * size and style.
+     * 
+     * @param style the style of font.
+     * @param size the size of font.
+     * 
+     * @return the Font object.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(int style, float size) {
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+
+        if ((style & BOLD) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.WEIGHT,
+                    TextAttribute.WEIGHT_BOLD);
+        } else if (derivefRequestedAttributes.get(TextAttribute.WEIGHT) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.WEIGHT);
+        }
+
+        if ((style & ITALIC) != 0) {
+            derivefRequestedAttributes.put(TextAttribute.POSTURE,
+                    TextAttribute.POSTURE_OBLIQUE);
+        } else if (derivefRequestedAttributes.get(TextAttribute.POSTURE) != null) {
+            derivefRequestedAttributes.remove(TextAttribute.POSTURE);
+        }
+
+        derivefRequestedAttributes.put(TextAttribute.SIZE, new Float(size));
+        return new Font(derivefRequestedAttributes);
+
+    }
+
+    /**
+     * Returns a new Font object with a new set of font attributes.
+     * 
+     * @param attributes the map of attributes.
+     * 
+     * @return the Font.
+     */
+    @SuppressWarnings("unchecked")
+    public Font deriveFont(Map<? extends Attribute, ?> attributes) {
+        Attribute[] avalAttributes = this.getAvailableAttributes();
+
+        Hashtable<Attribute, Object> derivefRequestedAttributes = (Hashtable<Attribute, Object>) fRequestedAttributes
+                .clone();
+        Object currAttribute;
+        for (Attribute element : avalAttributes) {
+            currAttribute = attributes.get(element);
+            if (currAttribute != null) {
+                derivefRequestedAttributes.put(element, currAttribute);
+            }
+        }
+        return new Font(derivefRequestedAttributes);
+    }
+
+    /**
+     * Compares the specified Object with the current Font.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is an instance of Font
+     * with the same family, size, and style as this Font, false otherwise. 
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj != null) {
+            try {
+                Font font = (Font) obj;
+
+                return ((this.style == font.style) && (this.size == font.size)
+                        && this.name.equals(font.name)
+                        && (this.pointSize == font.pointSize) && (this
+                        .getTransform()).equals(font.getTransform()));
+            } catch (ClassCastException e) {
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Gets the map of font's attributes.
+     * 
+     * @return the map of font's attributes.
+     */
+    @SuppressWarnings("unchecked")
+    public Map<TextAttribute, ?> getAttributes() {
+        return (Map<TextAttribute, ?>) fRequestedAttributes.clone();
+    }
+
+    /**
+     * Gets the keys of all available attributes.
+     * 
+     * @return the keys array of all available attributes.
+     */
+    public Attribute[] getAvailableAttributes() {
+        Attribute[] attrs = { TextAttribute.FAMILY, TextAttribute.POSTURE,
+                TextAttribute.SIZE, TextAttribute.TRANSFORM,
+                TextAttribute.WEIGHT, TextAttribute.SUPERSCRIPT,
+                TextAttribute.WIDTH };
+        return attrs;
+    }
+
+    /**
+     * Gets the baseline for this character.
+     * 
+     * @param c the character.
+     * 
+     * @return the baseline for this character.
+     */
+    public byte getBaselineFor(char c) {
+        // TODO: implement using TT BASE table data
+        return 0;
+    }
+
+    /**
+     * Gets the family name of the Font.
+     * 
+     * @return the family name of the Font.
+     */
+    public String getFamily() {
+        if (fRequestedAttributes != null) {
+            fRequestedAttributes.get(TextAttribute.FAMILY);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the family name of this Font associated with 
+     * the specified locale.
+     * 
+     * @param l the locale.
+     * 
+     * @return the family name of this Font associated with 
+     * the specified locale.
+     */
+    public String getFamily(Locale l) {
+        if (l == null) {
+            // awt.01='{0}' parameter is null
+            throw new NullPointerException(Messages.getString(
+                    "awt.01", "Locale")); //$NON-NLS-1$ //$NON-NLS-2$ 
+        }
+        return getFamily();
+    }
+
+    /**
+     * Gets a Font with the specified attribute set.
+     * 
+     * @param attributes the attributes to be assigned to the new Font.
+     * 
+     * @return the Font.
+     */
+    public static Font getFont(Map<? extends Attribute, ?> attributes) {
+        Font fnt = (Font) attributes.get(TextAttribute.FONT);
+        if (fnt != null) {
+            return fnt;
+        }
+        return new Font(attributes);
+    }
+
+    /**
+     * Gets a Font object from the system properties list with the specified name
+     * or returns the specified Font if there is no such property.
+     * 
+     * @param sp the specified property name.
+     * @param f the Font.
+     * 
+     * @return the Font object from the system properties list  with the specified name
+     * or the specified Font if there is no such property.
+     */
+    public static Font getFont(String sp, Font f) {
+        String pr = System.getProperty(sp);
+        if (pr == null) {
+            return f;
+        }
+        return decode(pr);
+    }
+
+    /**
+     * Gets a Font object from the system properties list with the specified name.
+     * 
+     * @param sp the system property name.
+     * 
+     * @return the Font, or null if there is no shuch property
+     * with the specified name. 
+     */
+    public static Font getFont(String sp) {
+        return getFont(sp, null);
+    }
+
+    /**
+     * Gets the font name.
+     * 
+     * @return the font name.
+     */
+    public String getFontName() {
+        if (fRequestedAttributes != null) {
+            fRequestedAttributes.get(TextAttribute.FAMILY);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the font name associated with the specified locale.
+     * 
+     * @param l the locale.
+     * 
+     * @return the font name associated with the specified locale.
+     */
+    public String getFontName(Locale l) {
+        return getFamily();
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param chars the chars array.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(char[] chars, int start, int end,
+            FontRenderContext frc) {
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        //FontMetrics fm = AndroidGraphics2D.getInstance().getFontMetrics();
+        FontMetrics fm = new FontMetricsImpl(this);
+        float[] fmet = {fm.getAscent(), fm.getDescent(), fm.getLeading()}; 
+        return new LineMetricsImpl(chars.length, fmet, null);
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param iter the CharacterIterator.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(CharacterIterator iter, int start,
+            int end, FontRenderContext frc) {
+
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        String resultString;
+        int iterCount;
+
+        iterCount = end - start;
+        if (iterCount < 0) {
+            resultString = ""; //$NON-NLS-1$
+        } else {
+            char[] chars = new char[iterCount];
+            int i = 0;
+            for (char c = iter.setIndex(start); c != CharacterIterator.DONE
+                    && (i < iterCount); c = iter.next()) {
+                chars[i] = c;
+                i++;
+            }
+            resultString = new String(chars);
+        }
+        return this.getLineMetrics(resultString, frc);
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param str the String.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(String str, FontRenderContext frc) {
+        //FontMetrics fm = AndroidGraphics2D.getInstance().getFontMetrics();
+        FontMetrics fm = new FontMetricsImpl(this);
+        float[] fmet = {fm.getAscent(), fm.getDescent(), fm.getLeading()};
+        //Log.i("FONT FMET", fmet.toString());
+        return new LineMetricsImpl(str.length(), fmet, null);
+
+    }
+
+    /**
+     * Returns a LineMetrics object created with the specified parameters.
+     * 
+     * @param str the String.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return the LineMetrics for the specified parameters.
+     */
+    public LineMetrics getLineMetrics(String str, int start, int end,
+            FontRenderContext frc) {
+        return this.getLineMetrics(str.substring(start, end), frc);
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param ci the specified CharacterIterator.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(CharacterIterator ci, int start,
+            int end, FontRenderContext frc) {
+        int first = ci.getBeginIndex();
+        int finish = ci.getEndIndex();
+        char[] chars;
+
+        if (start < first) {
+            // awt.95=Wrong start index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.95", start)); //$NON-NLS-1$
+        }
+        if (end > finish) {
+            // awt.96=Wrong finish index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.96", end)); //$NON-NLS-1$
+        }
+        if (start > end) {
+            // awt.97=Wrong range length: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.97", //$NON-NLS-1$
+                    (end - start)));
+        }
+
+        if (frc == null) {
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        chars = new char[end - start];
+
+        ci.setIndex(start);
+        for (int i = 0; i < chars.length; i++) {
+            chars[i] = ci.current();
+            ci.next();
+        }
+
+        return this.getStringBounds(chars, 0, chars.length, frc);
+
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param str the specified String.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(String str, FontRenderContext frc) {
+        char[] chars = str.toCharArray();
+        return this.getStringBounds(chars, 0, chars.length, frc);
+
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param str the specified String.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(String str, int start, int end,
+            FontRenderContext frc) {
+
+        return this.getStringBounds((str.substring(start, end)), frc);
+    }
+
+    /**
+     * Gets the logical bounds of the specified String in 
+     * the specified FontRenderContext. The logical bounds contains 
+     * the origin, ascent, advance, and height.
+     * 
+     * @param chars the specified character array.
+     * @param start the start offset.
+     * @param end the end offset.
+     * @param frc the FontRenderContext.
+     * 
+     * @return a Rectangle2D object.
+     */
+    public Rectangle2D getStringBounds(char[] chars, int start, int end,
+            FontRenderContext frc) {
+        if (start < 0) {
+            // awt.95=Wrong start index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.95", start)); //$NON-NLS-1$
+        }
+        if (end > chars.length) {
+            // awt.96=Wrong finish index: {0}
+            throw new IndexOutOfBoundsException(Messages.getString(
+                    "awt.96", end)); //$NON-NLS-1$
+        }
+        if (start > end) {
+            // awt.97=Wrong range length: {0}
+            throw new IndexOutOfBoundsException(Messages.getString("awt.97", //$NON-NLS-1$
+                    (end - start)));
+        }
+
+        if (frc == null) {
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$
+        }
+
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+
+        final int TRANSFORM_MASK = AffineTransform.TYPE_GENERAL_ROTATION
+                | AffineTransform.TYPE_GENERAL_TRANSFORM;
+        Rectangle2D bounds;
+
+        AffineTransform transform = getTransform();
+
+        // XXX: for transforms where an angle between basis vectors is not 90
+        // degrees Rectanlge2D class doesn't fit as Logical bounds.
+        if ((transform.getType() & TRANSFORM_MASK) == 0) {
+            int width = 0;
+            for (int i = start; i < end; i++) {
+                width += peer.charWidth(chars[i]);
+            }
+            //LineMetrics nlm = peer.getLineMetrics();
+            
+            LineMetrics nlm = getLineMetrics(chars, start, end, frc);
+            
+            bounds = transform.createTransformedShape(
+                    new Rectangle2D.Float(0, -nlm.getAscent(), width, nlm
+                            .getHeight())).getBounds2D();
+        } else {
+            int len = end - start;
+            char[] subChars = new char[len];
+            System.arraycopy(chars, start, subChars, 0, len);
+            bounds = createGlyphVector(frc, subChars).getLogicalBounds();
+        }
+        return bounds;
+    }
+
+    /**
+     * Gets the character's maximum bounds as defined in 
+     * the specified FontRenderContext.
+     * 
+     * @param frc the FontRenderContext.
+     * 
+     * @return the character's maximum bounds.
+     */
+    public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
+        if (frc == null) {
+            // awt.00=FontRenderContext is null
+            throw new NullPointerException(Messages.getString("awt.00")); //$NON-NLS-1$ 
+        }
+
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+
+        Rectangle2D bounds = peer.getMaxCharBounds(frc);
+        AffineTransform transform = getTransform();
+        // !! Documentation doesn't describe meaning of max char bounds
+        // for the fonts that have rotate transforms. For all transforms
+        // returned bounds are the bounds of transformed maxCharBounds
+        // Rectangle2D that corresponds to the font with identity transform.
+        // TODO: resolve this issue to return correct bounds
+        bounds = transform.createTransformedShape(bounds).getBounds2D();
+
+        return bounds;
+    }
+
+    /**
+     * Returns a new GlyphVector object performing full layout of
+     * the text.
+     * 
+     * @param frc the FontRenderContext.
+     * @param chars the character array to be layout.
+     * @param start the start offset of the text to use for 
+     * the GlyphVector.
+     * @param count the count of characters to use for 
+     * the GlyphVector.
+     * @param flags the flag indicating text direction: 
+     * LAYOUT_RIGHT_TO_LEFT, LAYOUT_LEFT_TO_RIGHT.
+     * 
+     * @return the GlyphVector.
+     */
+    public GlyphVector layoutGlyphVector(FontRenderContext frc, char[] chars,
+            int start, int count, int flags) {
+        // TODO: implement method for bidirectional text.
+        // At the moment only LTR and RTL texts supported.
+        if (start < 0) {
+            // awt.95=Wrong start index: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString(
+                    "awt.95", //$NON-NLS-1$
+                    start));
+        }
+
+        if (count < 0) {
+            // awt.98=Wrong count value, can not be negative: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString(
+                    "awt.98", //$NON-NLS-1$
+                    count));
+        }
+
+        if (start + count > chars.length) {
+            // awt.99=Wrong [start + count] is out of range: {0}
+            throw new ArrayIndexOutOfBoundsException(Messages.getString(
+                    "awt.99", //$NON-NLS-1$
+                    (start + count)));
+        }
+
+        char[] out = new char[count];
+        System.arraycopy(chars, start, out, 0, count);
+
+        return new CommonGlyphVector(out, frc, this, flags);
+    }
+
+    /**
+     * Returns the String representation of this Font.
+     * 
+     * @return the String representation of this Font.
+     */
+    @Override
+    public String toString() {
+        String stl = "plain"; //$NON-NLS-1$
+        String result;
+
+        if (this.isBold() && this.isItalic()) {
+            stl = "bolditalic"; //$NON-NLS-1$
+        }
+        if (this.isBold() && !this.isItalic()) {
+            stl = "bold"; //$NON-NLS-1$
+        }
+
+        if (!this.isBold() && this.isItalic()) {
+            stl = "italic"; //$NON-NLS-1$
+        }
+
+        result = this.getClass().getName() + "[family=" + this.getFamily() + //$NON-NLS-1$
+                ",name=" + this.name + //$NON-NLS-1$
+                ",style=" + stl + //$NON-NLS-1$
+                ",size=" + this.size + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        return result;
+    }
+
+    /**
+     * Gets the postscript name of this Font.
+     * 
+     * @return the postscript name of this Font.
+     */
+    public String getPSName() {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.getPSName();
+    }
+
+    /**
+     * Gets the logical name of this Font.
+     * 
+     * @return the logical name of this Font.
+     */
+    public String getName() {
+        return (this.name);
+    }
+
+    /**
+     * Gets the peer of this Font.
+     * 
+     * @return the peer of this Font.
+     * 
+     * @deprecated Font rendering is platform independent now.
+     */
+    @Deprecated
+    public java.awt.peer.FontPeer getPeer() {
+        if (fontPeer == null) {
+            fontPeer = (FontPeerImpl) Toolkit.getDefaultToolkit()
+                    .getGraphicsFactory().getFontPeer(this);
+        }
+        return fontPeer;
+
+    }
+
+    /**
+     * Gets the transform acting on this Font (from the Font's 
+     * attributes).
+     * 
+     * @return the transformation of this Font. 
+     */
+    public AffineTransform getTransform() {
+        Object transform = fRequestedAttributes.get(TextAttribute.TRANSFORM);
+
+        if (transform != null) {
+            if (transform instanceof TransformAttribute) {
+                return ((TransformAttribute) transform).getTransform();
+            }
+            if (transform instanceof AffineTransform) {
+                return new AffineTransform((AffineTransform) transform);
+            }
+        } else {
+            transform = new AffineTransform();
+        }
+        return (AffineTransform) transform;
+
+    }
+
+    /**
+     * Checks if this font is transformed or not.
+     * 
+     * @return true, if this font is transformed, false otherwise.
+     */
+    public boolean isTransformed() {
+        return this.transformed;
+    }
+
+    /**
+     * Checks if this font has plain style or not.
+     * 
+     * @return true, if this font has plain style, false otherwise.
+     */
+    public boolean isPlain() {
+        return (this.style == PLAIN);
+    }
+
+    /**
+     * Checks if this font has italic style or not.
+     * 
+     * @return true, if this font has italic style, false otherwise.
+     */
+    public boolean isItalic() {
+        return (this.style & ITALIC) != 0;
+    }
+
+    /**
+     * Checks if this font has bold style or not.
+     * 
+     * @return true, if this font has bold style, false otherwise.
+     */
+    public boolean isBold() {
+        return (this.style & BOLD) != 0;
+    }
+
+    /**
+     * Returns true if this Font has uniform line metrics. 
+     * 
+     * @return true if this Font has uniform line metrics, 
+     * false otherwise.
+     */
+    public boolean hasUniformLineMetrics() {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.hasUniformLineMetrics();
+    }
+
+    /**
+     * Returns hash code of this Font object.
+     * 
+     * @return the hash code of this Font object.
+
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(this.name);
+        hash.append(this.style);
+        hash.append(this.size);
+
+        return hash.hashCode();
+    }
+
+    /**
+     * Gets the style of this Font.
+     * 
+     * @return the style of this Font.
+     */
+    public int getStyle() {
+        return this.style;
+    }
+
+    /**
+     * Gets the size of this Font.
+     * 
+     * @return the size of this Font.
+     */
+    public int getSize() {
+        return this.size;
+    }
+
+    /**
+     * Gets the number of glyphs for this Font.
+     * 
+     * @return the number of glyphs for this Font.
+     */
+    public int getNumGlyphs() {
+        if (numGlyphs == -1) {
+            FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+            this.numGlyphs = peer.getNumGlyphs();
+        }
+        return this.numGlyphs;
+    }
+
+    /**
+     * Gets the glyphCode which is used as default glyph when this Font
+     * does not have a glyph for a specified unicode.
+     * 
+     * @return the missing glyph code.
+     */
+    public int getMissingGlyphCode() {
+        if (missingGlyphCode == -1) {
+            FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+            this.missingGlyphCode = peer.getMissingGlyphCode();
+        }
+        return this.missingGlyphCode;
+    }
+
+    /**
+     * Gets the float value of font's size.
+     * 
+     * @return the float value of font's size.
+     */
+    public float getSize2D() {
+        return this.pointSize;
+    }
+
+    /**
+     * Gets the italic angle of this Font.
+      * 
+     * @return the italic angle of this Font.
+     */
+    public float getItalicAngle() {
+        FontPeerImpl peer = (FontPeerImpl) this.getPeer();
+        return peer.getItalicAngle();
+    }
+
+    /**
+     * Creates the font with the specified font format and font file.
+     * 
+     * @param fontFormat the font format.
+     * @param fontFile the file object represented the input data 
+     * for the font.
+     * 
+     * @return the Font.
+     * 
+     * @throws FontFormatException is thrown if fontFile does not contain 
+     * the required font tables for the specified format.
+     * @throws IOException signals that an I/O exception has occurred.
+     */
+    public static Font createFont(int fontFormat, File fontFile)
+            throws FontFormatException, IOException {
+        // ???AWT not supported
+        InputStream is = new FileInputStream(fontFile);
+        try {
+            return createFont(fontFormat, is);
+        } finally {
+            is.close();
+        }
+    }
+
+    /**
+     * Creates the font with the specified font format and input stream.
+     * 
+     * @param fontFormat the font format.
+     * @param fontStream the input stream represented input data for 
+     * the font.
+     * 
+     * @return the Font.
+     * 
+     * @throws FontFormatException is thrown if fontFile does not contain 
+     * the required font tables for the specified format.
+     * @throws IOException signals that an I/O exception has occurred.
+     */
+    public static Font createFont(int fontFormat, InputStream fontStream)
+            throws FontFormatException, IOException {
+
+        // ???AWT not supported
+
+        BufferedInputStream buffStream;
+        int bRead = 0;
+        int size = 8192;
+        // memory page size, for the faster reading
+        byte buf[] = new byte[size];
+
+        if (fontFormat != TRUETYPE_FONT) { // awt.9A=Unsupported font format
+            throw new IllegalArgumentException(Messages.getString("awt.9A")); //$NON-NLS-1$ 
+        }
+        
+        /* Get font file in system-specific directory */
+
+        File fontFile = Toolkit.getDefaultToolkit().getGraphicsFactory()
+                .getFontManager().getTempFontFile();
+
+                // BEGIN android-modified
+        buffStream = new BufferedInputStream(fontStream, 8192);
+                // END android-modified
+        FileOutputStream fOutStream = new FileOutputStream(fontFile);
+
+        bRead = buffStream.read(buf, 0, size);
+
+        while (bRead != -1) {
+            fOutStream.write(buf, 0, bRead);
+            bRead = buffStream.read(buf, 0, size);
+        }
+
+        buffStream.close();
+        fOutStream.close();
+
+        Font font = null;
+
+        font = Toolkit.getDefaultToolkit().getGraphicsFactory().embedFont(
+                fontFile.getAbsolutePath());
+        if (font == null) { // awt.9B=Can't create font - bad font data
+            throw new FontFormatException(Messages.getString("awt.9B")); //$NON-NLS-1$
+        }
+        return font;
+    }
+
+}
diff --git a/awt/java/awt/FontFormatException.java b/awt/java/awt/FontFormatException.java
new file mode 100644
index 0000000..c017fd2
--- /dev/null
+++ b/awt/java/awt/FontFormatException.java
@@ -0,0 +1,41 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The FontFormatException class is used to provide notification
+ * and information that font can't be created.
+ */
+public class FontFormatException extends Exception {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4481290147811361272L;
+
+    /**
+     * Instantiates a new font format exception with detailed message.
+     * 
+     * @param reason the detailed message.
+     */
+    public FontFormatException(String reason) {
+        super(reason);
+    }
+
+}
diff --git a/awt/java/awt/FontMetrics.java b/awt/java/awt/FontMetrics.java
new file mode 100644
index 0000000..3948d73
--- /dev/null
+++ b/awt/java/awt/FontMetrics.java
@@ -0,0 +1,456 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+import java.text.CharacterIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The FontMetrics class contains information about the rendering 
+ * of a particular font on a particular screen.
+ * <p>
+ * Each character in the Font has three values that help define where 
+ * to place it: an ascent, a descent, and an advance. The ascent is the 
+ * distance the character extends above the baseline. The descent is
+ * the distance the character extends below the baseline. 
+ * The advance width defines the position at which the next character
+ * should be placed.
+ * <p>
+ * An array of characters or a string has an ascent, a descent,
+ *  and an advance width too. The ascent or descent of the array 
+ *  is specified by the maximum ascent or descent of the characters 
+ *  in the array. The advance width is the sum of the advance widths 
+ *  of each of the characters in the character array.
+ */
+public abstract class FontMetrics implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 1681126225205050147L;
+
+    /** The font from which the FontMetrics is created. */
+    protected Font font;
+
+    /**
+     * Instantiates a new font metrics from the specified Font.
+     * 
+     * @param fnt the Font.
+     */
+    protected FontMetrics(Font fnt) {
+        this.font = fnt;
+    }
+
+    /**
+     * Returns the String representation of this FontMetrics.
+     * 
+     * @return the string
+     */
+    @Override
+    public String toString() {
+        return this.getClass().getName() +
+                "[font=" + this.getFont() + //$NON-NLS-1$
+                "ascent=" + this.getAscent() + //$NON-NLS-1$
+                ", descent=" + this.getDescent() + //$NON-NLS-1$
+                ", height=" + this.getHeight() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Gets the font associated with this FontMetrics.
+     * 
+     * @return the font associated with this FontMetrics.
+     */
+    public Font getFont() {
+        return font;
+    }
+
+    /**
+     * Gets the height of the text line in this Font.
+     * 
+     * @return the height of the text line in this Font.
+     */
+    public int getHeight() {
+        return this.getAscent() + this.getDescent() + this.getLeading();
+    }
+
+    /**
+     * Gets the font ascent of the Font associated with this FontMetrics.
+     * The font ascent is the distance from the font's baseline to 
+     * the top of most alphanumeric characters.
+     * 
+     * @return the ascent of the Font associated with this FontMetrics.
+     */
+    public int getAscent() {
+        return 0;
+    }
+
+    /**
+     * Gets the font descent of the Font associated with this FontMetrics.
+     * The font descent is the distance from the font's baseline to 
+     * the bottom of most alphanumeric characters with descenders.
+     * 
+     * @return the descent of the Font associated with this FontMetrics.
+     */
+    public int getDescent() {
+        return 0;
+    }
+
+    /**
+     * Gets the leading of the Font associated with this FontMetrics.
+     * 
+     * @return the leading of the Font associated with this FontMetrics.
+     */
+    public int getLeading() {
+        return 0;
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified CharacterIterator
+     * in the specified Graphics.
+     * 
+     * @param ci the CharacterIterator.
+     * @param beginIndex the offset.
+     * @param limit the number of characters to be used.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified CharacterIterator
+     * in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(CharacterIterator ci, int beginIndex,
+                                        int limit, Graphics context) {
+        return font.getLineMetrics(ci, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified String
+     * in the specified Graphics.
+     * 
+     * @param str the String.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified String
+     * in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(String str, Graphics context) {
+        return font.getLineMetrics(str, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified character 
+     * array in the specified Graphics.
+     * 
+     * @param chars the character array.
+     * @param beginIndex the offset of array.
+     * @param limit the number of characters to be used.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified character 
+     * array in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(char[] chars, int beginIndex, int limit,
+                                        Graphics context) {
+        return font.getLineMetrics(chars, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the LineMetrics object for the specified String
+     * in the specified Graphics.
+     * 
+     * @param str the String.
+     * @param beginIndex the offset.
+     * @param limit the number of characters to be used.
+     * @param context the Graphics.
+     * 
+     * @return the LineMetrics object for the specified String
+     * in the specified Graphics.
+     */
+    public LineMetrics getLineMetrics(String str, int beginIndex, int limit,
+                                        Graphics context) {
+        return font.getLineMetrics(str, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Returns the character's maximum bounds in the specified 
+     * Graphics context.
+     * 
+     * @param context the Graphics context.
+     * 
+     * @return the character's maximum bounds in the specified 
+     * Graphics context.
+     */
+    public Rectangle2D getMaxCharBounds(Graphics context) {
+        return this.font.getMaxCharBounds(this.getFRCFromGraphics(context));
+    }
+    
+    /**
+     * Gets the bounds of the specified CharacterIterator 
+     * in the specified Graphics context.
+     * 
+     * @param ci the CharacterIterator.
+     * @param beginIndex the begin offset of the array.
+     * @param limit the number of characters.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified CharacterIterator 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(CharacterIterator ci, int beginIndex,
+            int limit, Graphics context) {
+        return font.getStringBounds(ci, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the bounds of the specified String 
+     * in the specified Graphics context.
+     * 
+     * @param str the String.
+     * @param beginIndex the begin offset of the array.
+     * @param limit the number of characters.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified String 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(String str, int beginIndex, int limit,
+            Graphics context) {
+        return font.getStringBounds(str, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+
+    /**
+     * Gets the bounds of the specified characters array 
+     * in the specified Graphics context.
+     * 
+     * @param chars the characters array.
+     * @param beginIndex the begin offset of the array.
+     * @param limit the number of characters.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified characters array 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(char[] chars, int beginIndex, int limit,
+            Graphics context) {
+        return font.getStringBounds(chars, beginIndex, limit, 
+                this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Gets the bounds of the specified String 
+     * in the specified Graphics context.
+     * 
+     * @param str the String.
+     * @param context the Graphics.
+     * 
+     * @return the bounds of the specified String 
+     * in the specified Graphics context.
+     */
+    public Rectangle2D getStringBounds(String str, Graphics context) {
+        return font.getStringBounds(str, this.getFRCFromGraphics(context));
+    }
+
+    /**
+     * Checks if the Font has uniform line metrics or not. 
+     * The Font can contain characters of other fonts for 
+     * covering character set. In this case the Font isn't
+     * uniform. 
+     *  
+     * @return true, if the Font has uniform line metrics, 
+     * false otherwise.
+     */
+    public boolean hasUniformLineMetrics() {
+        return this.font.hasUniformLineMetrics();
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point on the string's baseline showing the specified array 
+     * of bytes in this Font.   
+     * 
+     * @param data the array of bytes to be measured.
+     * @param off the start offset.
+     * @param len the number of bytes to be measured.
+     * 
+     * @return the advance width of the array.
+     */
+    public int bytesWidth(byte[] data, int off, int len) {
+        int width = 0;
+        if ((off >= data.length) || (off < 0)){
+            // awt.13B=offset off is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13B")); //$NON-NLS-1$
+        }
+
+        if ((off+len > data.length)){
+            // awt.13C=number of elemets len is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13C")); //$NON-NLS-1$
+        }
+
+        for (int i = off; i < off+len; i++){
+            width += charWidth(data[i]);
+        }
+
+        return width;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point on the string's baseline showing the specified array 
+     * of characters in this Font.   
+     * 
+     * @param data the array of characters to be measured.
+     * @param off the start offset.
+     * @param len the number of bytes to be measured.
+     * 
+     * @return the advance width of the array.
+     */
+    public int charsWidth(char[] data, int off , int len){
+        int width = 0;
+        if ((off >= data.length) || (off < 0)){
+            // awt.13B=offset off is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13B")); //$NON-NLS-1$
+        }
+
+        if ((off+len > data.length)){
+            // awt.13C=number of elemets len is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.13C")); //$NON-NLS-1$
+        }
+
+        for (int i = off; i < off+len; i++){
+            width += charWidth(data[i]);
+        }
+
+        return width;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point of the specified character in this Font.   
+     * 
+     * @param ch the specified unicode point code of 
+     * character to be measured.
+     * 
+     * @return the advance width of the character.
+     */
+    public int charWidth(int ch) {
+        return 0;
+    }
+
+    /**
+     * Returns the distance from the leftmost point to the rightmost 
+     * point of the specified character in this Font.   
+     * 
+     * @param ch the specified character to be measured.
+     * 
+     * @return the advance width of the character.
+     */
+    public int charWidth(char ch) {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum advance width of character in this Font.
+     * 
+     * @return the maximum advance width of character in this Font.
+     */
+    public int getMaxAdvance() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font ascent of the Font associated with 
+     * this FontMetrics.
+     * 
+     * @return the maximum font ascent of the Font associated with 
+     * this FontMetrics.
+     */
+    public int getMaxAscent() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font descent of character in this Font.
+     * 
+     * @return the maximum font descent of character in this Font.
+     * 
+     * @deprecated Replaced by getMaxDescent() method.
+     */
+    @Deprecated
+    public int getMaxDecent() {
+        return 0;
+    }
+
+    /**
+     * Gets the maximum font descent of character in this Font.
+     * 
+     * @return the maximum font descent of character in this Font.
+     */
+    public int getMaxDescent() {
+        return 0;
+    }
+
+    /**
+     * Gets the advance widths of the characters in the Font.
+     * 
+     * @return the advance widths of the characters in the Font.
+     */
+    public int[] getWidths() {
+        return null;
+    }
+
+    /**
+     * Returns the advance width for the specified String in this Font.
+     * 
+     * @param str String to be measured. 
+     * 
+     * @return the the advance width for the specified String 
+     * in this Font.
+     */
+    public int stringWidth(String str) {
+        return 0;
+    }
+    
+    /**
+     * Returns FontRenderContext instanse of the Graphics context specified.
+     * 
+     * @param context the specified Graphics context
+     * 
+     * @return a FontRenderContext of the specified Graphics context.
+     */
+    private FontRenderContext getFRCFromGraphics(Graphics context){
+        FontRenderContext frc;
+        if (context instanceof Graphics2D) {
+            frc = ((Graphics2D)context).getFontRenderContext();
+        } else {
+            frc = new FontRenderContext(null, false, false);
+        }
+
+        return frc;
+    }
+}
+
diff --git a/awt/java/awt/GradientPaint.java b/awt/java/awt/GradientPaint.java
new file mode 100644
index 0000000..0e06528
--- /dev/null
+++ b/awt/java/awt/GradientPaint.java
@@ -0,0 +1,219 @@
+/*
+ *  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 java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GradientPaint class defines a way to fill a Shape with a linear color
+ * gradient pattern. 
+ * <p>
+ * The GradientPaint's fill pattern is determined by two points and two colors, 
+ * plus the cyclic mode option.
+ * Each of the two points is painted with its corresponding color, and on 
+ * the line segment connecting the two points, the color is proportionally
+ * changed between the two colors. For points on the same line which are not 
+ * between the two specified points (outside of the connecting segment) their
+ * color is determined by the cyclic mode option. If the mode is cyclic, then
+ * the rest of the line repeats the color pattern of the connecting segment, 
+ * cycling back and forth between the two colors. If not, the mode is acyclic 
+ * which means that all points 
+ * on the line outside the connecting line segment are given the same 
+ * color as the closest of the two specified points.
+ * <p>
+ * The color of points that are not on the line connecting the two 
+ * specified points are given by perpendicular projection: by taking 
+ * the set of lines perpendicular to the connecting line and for each 
+ * one, the whole line is colored with the same color.
+ */
+public class GradientPaint implements Paint {
+    
+    /** The start point color. */
+    Color color1;
+
+    /** The end color point. */
+    Color color2;
+
+    /** The location of the start point. */
+    Point2D point1;
+
+    /** The location of the end point. */
+    Point2D point2;
+
+    /** The indicator of cycle filling. If TRUE filling 
+     * repeated outside points stripe, if FALSE solid color filling outside. */
+    boolean cyclic;
+
+    /**
+     * Instantiates a new GradientPaint with cyclic or acyclic mode.
+     * 
+     * @param point1 the first specified point.
+     * @param color1 the Color of the first specified point. 
+     * @param point2 the second specified point.
+     * @param color2 the Color of the second specified point.
+     * @param cyclic the cyclic mode - true if the gradient pattern should cycle 
+     * repeatedly between the two colors; false otherwise.
+     */
+    public GradientPaint(Point2D point1, Color color1, Point2D point2,
+            Color color2, boolean cyclic) {
+        if (point1 == null || point2 == null) {
+            // awt.6D=Point is null
+            throw new NullPointerException(Messages.getString("awt.6D")); //$NON-NLS-1$
+        }
+        if (color1 == null || color2 == null) {
+            // awt.6E=Color is null
+            throw new NullPointerException(Messages.getString("awt.6E")); //$NON-NLS-1$
+        }
+
+        this.point1 = point1;
+        this.point2 = point2;
+        this.color1 = color1;
+        this.color2 = color2;
+        this.cyclic = cyclic;
+    }
+
+    /**
+     * Instantiates a new GradientPaint with cyclic or acyclic mode;
+     * points are specified by coordinates.
+     * 
+     * @param x1 the X coordinate of the first point.
+     * @param y1 the Y coordinate of the first point.
+     * @param color1 the color of the first point.
+     * @param x2 the X coordinate of the second point.
+     * @param y2 the Y coordinate of the second point.
+     * @param color2 the color of the second point.
+     * @param cyclic the cyclic mode - true if the gradient pattern should cycle 
+     * repeatedly between the two colors; false otherwise.
+     */
+    public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2,
+            boolean cyclic) {
+        this(new Point2D.Float(x1, y1), color1, new Point2D.Float(x2, y2), color2, cyclic);
+    }
+
+    /**
+     * Instantiates a new acyclic GradientPaint;
+     * points are specified by coordinates.
+     * 
+     * @param x1 the X coordinate of the first point.
+     * @param y1 the Y coordinate of the first point.
+     * @param color1 the color of the first point.
+     * @param x2 the X coordinate of the second point.
+     * @param y2 the Y coordinate of the second point.
+     * @param color2 the color of the second point.
+     */
+    public GradientPaint(float x1, float y1, Color color1, float x2, float y2, Color color2) {
+        this(x1, y1, color1, x2, y2, color2, false);
+    }
+
+    /**
+     * Instantiates a new acyclic GradientPaint.
+     * 
+     * @param point1 the first specified point.
+     * @param color1 the Color of the first specified point. 
+     * @param point2 the second specified point.
+     * @param color2 the Color of the second specified point.
+     */
+    public GradientPaint(Point2D point1, Color color1, Point2D point2, Color color2) {
+        this(point1, color1, point2, color2, false);
+    }
+
+    /**
+     * Creates PaintContext for a color pattern generating. 
+     * 
+     * @param cm the ColorModel of the Paint data.
+     * @param deviceBounds the bounding Rectangle of graphics primitives
+     * being rendered in the device space. 
+     * @param userBounds tthe bounding Rectangle of graphics primitives
+     * being rendered in the user space. 
+     * @param t the AffineTransform from user space into device space.
+     * @param hints the RrenderingHints object.
+     * 
+     * @return the PaintContext for color pattern generating.
+     * 
+     * @see java.awt.Paint#createContext(java.awt.image.ColorModel, java.awt.Rectangle, java.awt.geom.Rectangle2D, java.awt.geom.AffineTransform, java.awt.RenderingHints)
+     */
+    public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+            Rectangle2D userBounds, AffineTransform t, RenderingHints hints) {
+        return new GradientPaintContext(cm, t, point1, color1, point2, color2, cyclic);
+    }
+
+    /**
+     * Gets the color of the first point.
+     * 
+     * @return the color of the first point.
+     */
+    public Color getColor1() {
+        return color1;
+    }
+
+    /**
+     * Gets the color of the second point.
+     * 
+     * @return the color of the second point.
+     */
+    public Color getColor2() {
+        return color2;
+    }
+
+    /**
+     * Gets the first point.
+     * 
+     * @return the Point object - the first point. 
+     */
+    public Point2D getPoint1() {
+        return point1;
+    }
+
+    /**
+     * Gets the second point.
+     * 
+     * @return the Point object - the second point.
+     */
+    public Point2D getPoint2() {
+        return point2;
+    }
+
+    /**
+     * Gets the transparency mode for the GradientPaint.
+     * 
+     * @return the transparency mode for the GradientPaint.
+     * 
+     * @see java.awt.Transparency#getTransparency()
+     */
+    public int getTransparency() {
+        int a1 = color1.getAlpha();
+        int a2 = color2.getAlpha();
+        return (a1 == 0xFF && a2 == 0xFF) ? OPAQUE : TRANSLUCENT;
+    }
+
+    /**
+     * Returns the GradientPaint mode: true for cyclic mode, false for
+     * acyclic mode.
+     * 
+     * @return true if the gradient cycles repeatedly between the two colors; 
+     * false otherwise.
+     */
+    public boolean isCyclic() {
+        return cyclic;
+    }
+}
diff --git a/awt/java/awt/GradientPaintContext.java b/awt/java/awt/GradientPaintContext.java
new file mode 100644
index 0000000..74575f5
--- /dev/null
+++ b/awt/java/awt/GradientPaintContext.java
@@ -0,0 +1,204 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+class GradientPaintContext implements PaintContext {
+
+    /**
+     * The size of noncyclic part of color lookup table
+     */
+    static int LOOKUP_SIZE = 256;
+    
+    /**
+     * The index mask to lookup color in the table
+     */
+    static int LOOKUP_MASK = 0x1FF;
+    
+    /**
+     * The min value equivalent to zero. If absolute value less then ZERO it considered as zero.  
+     */
+    static double ZERO = 1E-10;
+
+    /**
+     * The ColorModel user defined for PaintContext
+     */
+    ColorModel cm;
+    
+    /**
+     * The indicator of cycle filling.
+     */
+    boolean cyclic;
+    
+    /**
+     * The integer color value of the start point
+     */
+    int c1;
+    
+    /**
+     * The integer color value of the end point
+     */
+    int c2;
+    
+    /**
+     * The lookup gradient color table 
+     */
+    int[] table;
+
+    /**
+     * The tempopary pre-calculated value to evalutae color index 
+     */
+    int dx;
+    
+    /**
+     * The tempopary pre-calculated value to evalutae color index 
+     */
+    int dy;
+    
+    /**
+     * The tempopary pre-calculated value to evalutae color index 
+     */
+    int delta;
+    
+    /**
+     * Constructs a new GradientPaintcontext
+     * @param cm - not used
+     * @param t - the fill transformation
+     * @param point1 - the start fill point
+     * @param color1 - color of the start point 
+     * @param point2 - the end fill point
+     * @param color2 - color of the end point
+     * @param cyclic - the indicator of cycle filling
+     */
+    GradientPaintContext(ColorModel cm, AffineTransform t, Point2D point1, Color color1, Point2D point2, Color color2, boolean cyclic) {
+        this.cyclic = cyclic;
+        this.cm = ColorModel.getRGBdefault();
+
+        c1 = color1.getRGB();
+        c2 = color2.getRGB();
+
+        double px = point2.getX() - point1.getX();
+        double py = point2.getY() - point1.getY();
+
+        Point2D p = t.transform(point1, null);
+        Point2D bx = new Point2D.Double(px, py);
+        Point2D by = new Point2D.Double(py, -px);
+
+        t.deltaTransform(bx, bx);
+        t.deltaTransform(by, by);
+
+        double vec = bx.getX() * by.getY() - bx.getY() * by.getX();
+
+        if (Math.abs(vec) < ZERO) {
+            dx = dy = delta = 0;
+            table = new int[1];
+            table[0] = c1;
+        } else {
+            double mult = LOOKUP_SIZE * 256 / vec;
+            dx = (int)(by.getX() * mult);
+            dy = (int)(by.getY() * mult);
+            delta = (int)((p.getX() * by.getY() - p.getY() * by.getX()) * mult);
+            createTable();
+        }
+    }
+
+    /**
+     * Create color index lookup table. Calculate 256 step trasformation from 
+     * the start point color to the end point color. Colors multiplied by 256 to do integer calculations. 
+     */
+    void createTable() {
+        double ca = (c1 >> 24) & 0xFF;
+        double cr = (c1 >> 16) & 0xFF;
+        double cg = (c1 >> 8) & 0xFF;
+        double cb = c1 & 0xFF;
+
+        double k = 1.0 / LOOKUP_SIZE;
+        double da = (((c2 >> 24) & 0xFF) - ca) * k;
+        double dr = (((c2 >> 16) & 0xFF) - cr) * k;
+        double dg = (((c2 >> 8) & 0xFF) - cg) * k;
+        double db = ((c2 & 0xFF) - cb) * k;
+
+        table = new int[cyclic ? LOOKUP_SIZE + LOOKUP_SIZE : LOOKUP_SIZE];
+        for(int i = 0; i < LOOKUP_SIZE; i++) {
+            table[i] =
+                (int)ca << 24 |
+                (int)cr << 16 |
+                (int)cg << 8 |
+                (int)cb;
+            ca += da;
+            cr += dr;
+            cg += dg;
+            cb += db;
+        }
+        if (cyclic) {
+            for(int i = 0; i < LOOKUP_SIZE; i++) {
+                table[LOOKUP_SIZE + LOOKUP_SIZE - 1 - i] = table[i];
+            }
+        }
+    }
+
+    public ColorModel getColorModel() {
+        return cm;
+    }
+
+    public void dispose() {
+    }
+
+    public Raster getRaster(int x, int y, int w, int h) {
+        WritableRaster rast = cm.createCompatibleWritableRaster(w, h);
+
+        int[] buf = ((DataBufferInt)rast.getDataBuffer()).getData();
+
+        int c = x * dy - y * dx - delta;
+        int cx = dy;
+        int cy = - w * dy - dx;
+        int k = 0;
+
+        if (cyclic) {
+            for(int j = 0; j < h; j++) {
+                for(int i = 0; i < w; i++) {
+                    buf[k++] = table[(c >> 8) & LOOKUP_MASK];
+                    c += cx;
+                }
+                c += cy;
+            }
+        } else {
+            for(int j = 0; j < h; j++) {
+                for(int i = 0; i < w; i++) {
+                    int index = c >> 8;
+                    buf[k++] = index < 0 ? c1 : index >= LOOKUP_SIZE ? c2 : table[index];
+                    c += cx;
+                }
+                c += cy;
+            }
+        }
+
+        return rast;
+    }
+
+}
+
diff --git a/awt/java/awt/Graphics.java b/awt/java/awt/Graphics.java
new file mode 100644
index 0000000..c20f6bc
--- /dev/null
+++ b/awt/java/awt/Graphics.java
@@ -0,0 +1,737 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.ImageObserver;
+import java.text.AttributedCharacterIterator;
+
+/**
+ * The abstract Graphics class allows applications to draw on a screen
+ * or other rendering target. There are several properties which 
+ * define rendering options: origin point, clipping area, color, font.
+ * <br><br>
+ * The origin point specifies the beggining of the clipping area coordinate 
+ * system. All coordinates used in rendering operations are computed with 
+ * respect to this point. The clipping area defines the boundaries where 
+ * rendering operations can be performed. Rendering operations can't modify 
+ * pixels outside of the clipping area.
+ * <br><br>
+ * The draw and fill methods allow applications to drawing shapes, text, 
+ * images with specified font and color options in the specified part 
+ * of the screen.
+ *    
+ */
+public abstract class Graphics {
+
+    // Constructors
+
+    /**
+     * Instantiates a new Graphics. This constructor is default for Graphics and
+     * can not be called directly. 
+     */
+    protected Graphics() {
+    }
+
+    // Public methods
+
+    /**
+     * Creates a copy of the Graphics object with a new origin and a new 
+     * specified clip area. The new clip area is the rectangle defined by 
+     * the origin point with coordinates X,Y and the given width and height. 
+     * The coordinates of all subsequent rendering operations will be computed
+     * with respect to the new origin and can be performed only within the 
+     * range of the clipping area dimentions. 
+     *  
+     * @param x the X coordinate of the original point
+     * @param y the Y coordinate of the original point
+     * @param width the width of clipping area
+     * @param height the height of clipping area
+     * 
+     * @return the Graphics object with new origin point and clipping area. 
+     */
+    public Graphics create(int x, int y, int width, int height) {
+        Graphics res = create();
+        res.translate(x, y);
+        res.clipRect(0, 0, width, height);
+        return res;
+    }
+
+    /**
+     * Draws the higlighted outline of a rectangle.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     */
+    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
+        // Note: lighter/darker colors should be used to draw 3d rect.
+        // The resulting rect is (width+1)x(height+1). Stroke and paint attributes of
+        // the Graphics2D should be reset to the default values.
+        // fillRect is used instead of drawLine to bypass stroke
+        // reset/set and rasterization.
+
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+        }
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y+1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x+width, y, 1, height);
+        fillRect(x+1, y+height, width, 1);
+    }
+
+    /**
+     * Draws the text represented by byte array. This method uses the current 
+     * font and color for rendering.
+     * 
+     * @param bytes the byte array which contains the text to be drawn. 
+     * @param off the offset within the byte array of the text to be drawn.
+     * @param len the number of bytes of text to draw. 
+     * @param x the X coordinate where the text is to be drawn.
+     * @param y the Y coordinate where the text is to be drawn.
+     */
+    public void drawBytes(byte[] bytes, int off, int len, int x, int y) {
+        drawString(new String(bytes, off, len), x, y);
+    }
+
+    /**
+     * Draws the text represented by character array. This method uses the 
+     * current font and color for rendering.
+     * 
+     * @param chars the character array. 
+     * @param off the offset within the character array of the text to be drawn.
+     * @param len the number of characters which will be drawn. 
+     * @param x the X coordinate where the text is to be drawn.
+     * @param y the Y coordinate where the text is to be drawn.
+     */
+    public void drawChars(char[] chars, int off, int len, int x, int y) {
+        drawString(new String(chars, off, len), x, y);
+    }
+
+    /**
+     * Draws the outline of a polygon which is defined by Polygon object.
+     * 
+     * @param p the Polygon object.
+     */
+    public void drawPolygon(Polygon p) {
+        drawPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+
+    /**
+     * Draws the rectangle with the specified width and length and top left 
+     * corner coordinates.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     */
+    public void drawRect(int x, int y, int width, int height) {
+        int []xpoints = {x, x, x+width, x+width};
+        int []ypoints = {y, y+height, y+height, y};
+
+        drawPolygon(xpoints, ypoints, 4);
+    }
+
+    /**
+     * Fills the higlighted outline of a rectangle.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     */
+    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
+        // Note: lighter/darker colors should be used to draw 3d rect.
+        // The resulting rect is (width)x(height), same as fillRect.
+        // Stroke and paint attributes of the Graphics2D should be reset
+        // to the default values. fillRect is used instead of drawLine to
+        // bypass stroke reset/set and line rasterization.
+        
+        Color color = getColor();
+        Color colorUp, colorDown;
+        if (raised) {
+            colorUp = color.brighter();
+            colorDown = color.darker();
+            setColor(color);
+        } else {
+            colorUp = color.darker();
+            colorDown = color.brighter();
+            setColor(colorUp);
+        }
+
+        width--;
+        height--;
+        fillRect(x+1, y+1, width-1, height-1);
+
+        setColor(colorUp);
+        fillRect(x, y, width, 1);
+        fillRect(x, y+1, 1, height);
+
+        setColor(colorDown);
+        fillRect(x+width, y, 1, height);
+        fillRect(x+1, y+height, width, 1);
+    }
+
+    /**
+     * Fills the polygon with the current color.
+     * 
+     * @param p the Polygon object.
+     */
+    public void fillPolygon(Polygon p) {
+        fillPolygon(p.xpoints, p.ypoints, p.npoints);
+    }
+
+    /**
+     * Disposes of the Graphics.
+     */
+    @Override
+    public void finalize() {
+    }
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle 
+     * and copies it to an existing rectangle.
+     *  
+     * @param r a Rectangle object where the current clipping area 
+     * bounds are to be copied.
+     * 
+     * @return the bounds of the current clipping area.
+     */
+    public Rectangle getClipBounds(Rectangle r) {
+        Shape clip = getClip();
+
+        if (clip != null) {
+            // TODO: Can we get shape bounds without creating Rectangle object?
+            Rectangle b = clip.getBounds();
+            r.x = b.x;
+            r.y = b.y;
+            r.width = b.width;
+            r.height = b.height;
+        }
+
+        return r;
+    }
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle.
+     * 
+     * @return a Rectangle object 
+     * 
+     * @deprecated Use {@link #getClipBounds()}
+     */
+    @Deprecated
+    public Rectangle getClipRect() {
+        return getClipBounds();
+    }
+
+    /**
+     * Gets the font metrics of the current font. 
+     * The font metrics object contains information about the rendering 
+     * of a particular font.
+     * 
+     * @return the font metrics of current font.
+     */
+    public FontMetrics getFontMetrics() {
+        return getFontMetrics(getFont());
+    }
+
+    /**
+     * Determines whether or not the specified rectangle intersects the 
+     * current clipping area.
+     *  
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     * 
+     * @return true, if the specified rectangle intersects the current clipping area, 
+     * overwise false. 
+     */
+    public boolean hitClip(int x, int y, int width, int height) {
+        // TODO: Create package private method Rectangle.intersects(int, int, int, int);
+        return getClipBounds().intersects(new Rectangle(x, y, width, height));
+    }
+
+    /**
+     * Returns string which represents this Graphics object.
+     * 
+     * @return the string which represents this Graphics object.
+     */
+    @Override
+    public String toString() {
+        // TODO: Think about string representation of Graphics.
+        return "Graphics"; //$NON-NLS-1$
+    }
+
+    // Abstract methods
+
+    /**
+     * Clears the specified rectangle. This method fills specified rectangle 
+     * with background color.  
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     */
+    public abstract void clearRect(int x, int y, int width, int height);
+
+    /**
+     * Intersects the current clipping area with a new rectangle. 
+     * If the current clipping area is not defined, the rectangle 
+     * becomes a new clipping area. Rendering operations are only allowed 
+     * within the new the clipping area.    
+     *          
+     * @param x the X coordinate of the rectangle for intersection. 
+     * @param y the Y coordinate of the rectangle for intersection.
+     * @param width the width of the rectangle for intersection.
+     * @param height the height of the rectangle for intersection.
+     */
+    public abstract void clipRect(int x, int y, int width, int height);
+
+    /**
+     * Copies the rectangle area to another area specified by 
+     * a distance (dx, dy) from the original rectangle's location. 
+     * Positive dx and dy values give a new location defined by 
+     * translation to the right and down from the original location, 
+     * negative dx and dy values - to the left and up.
+     * <br><br>
+     * 
+     * @param sx the X coordinate of the rectangle which will be copied. 
+     * @param sy the Y coordinate of the rectangle which will be copied.
+     * @param width the width of the rectangle which will be copied.
+     * @param height the height of the rectangle which will be copied.
+     * @param dx the horizontal distance from the source rectangle's 
+     * location to the copy's location. 
+     * @param dy the vertical distance from the source rectangle's 
+     * location to the copy's location. 
+     */
+    public abstract void copyArea(int sx, int sy, int width, int height, int dx, int dy);
+
+    /**
+     * Creates a new copy of this Graphics.
+     * 
+     * @return a new Graphics context which is a copy of this Graphics.
+     */
+    public abstract Graphics create();
+
+    /**
+     * Disposes of the Graphics. This Graphics object can not be used after 
+     * calling this method.  
+     */
+    public abstract void dispose();
+
+    /**
+     * Draws the arc covering the specified rectangle and using the current color. 
+     * The rectangle is defined by the origin point (X, Y) and dimentions 
+     * (width and height). The arc center is the the center of specified rectangle. 
+     * The angle origin is 3 o'clock position, the positive angle is counted as a 
+     * counter-clockwise rotation, the negotive angle is counted as clockwise rotation.   
+     * 
+     * @param x the X origin coordinate of the rectangle which scales the arc. 
+     * @param y the Y origin coordinate of the rectangle which scales the arc.
+     * @param width the width of the rectangle which scales the arc.
+     * @param height the height of the rectangle which scales the arc.
+     * @param sa start angle - the origin angle of arc.
+     * @param ea arc angle - the angular arc value relative to the start angle. 
+     */
+    public abstract void drawArc(int x, int y, int width, int height, int sa, int ea);
+
+    /**
+     * Draws the specified image with the defined background color. 
+     * The top left corner of image will be drawn at point (x, y) 
+     * in current coordinate system. The image loading process notifies the
+     * specified Image Observer. This method returns true if the image
+     * has loaded, overwise it returns false.       
+     * 
+     * @param img the image which will be drawn. 
+     * @param x the X coordinate of the image top left corner. 
+     * @param y the Y coordinate of the image top left corner. 
+     * @param bgcolor the background color.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Draws the specified image. 
+     * The top left corner of image will be drawn at point (x, y) 
+     * in current coordinate system. The image loading process notifies the
+     * specified Image Observer. This method returns true if the image
+     * has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn. 
+     * @param x the X coordinate of the image top left corner. 
+     * @param y the Y coordinate of the image top left corner. 
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, ImageObserver observer);
+
+    /**
+     * Scales the specified image to fit in the specified rectangle and 
+     * draws it with the defined background color. The top left corner 
+     * of the image will be drawn at the point (x, y) in current coordinate 
+     * system. The non-opaque pixels will be drawn in the background color. 
+     * The image loading process notifies the specified Image Observer. 
+     * This method returns true if the image has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param x the X coordinate of the image's top left corner.
+     * @param y the Y coordinate of the image's top left corner. 
+     * @param width the width of rectangle which scales the image.
+     * @param height the height of rectangle which scales the image.
+     * @param bgcolor the background color.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Scales the specified image to fit in the specified rectangle and 
+     * draws it. The top left corner of the image will be drawn at the 
+     * point (x, y) in current coordinate system. The image loading process 
+     * notifies the specified Image Observer. 
+     * This method returns true if the image has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param x the X coordinate of the image top left corner.
+     * @param y the Y coordinate of the image top left corner. 
+     * @param width the width of rectangle which scales the image.
+     * @param height the height of rectangle which scales the image.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer);
+
+    /**
+     * Scales the specified area of the specified image to fit in the rectangle area 
+     * defined by its corners coordinates and draws the sub-image with the specified 
+     * background color. The sub-image to be drawn is defined by its top left 
+     * corner coordinates (sx1, sy1) and bottom right corner coordinates (sx2, sy2)
+     * computed with respect to the origin (top left corner) of the source image.
+     * The non opaque pixels will be drawn in the background color. The 
+     * image loading process notifies specified Image Observer. 
+     * This method returns true if the image
+     * has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param dx1 the X top left corner coordinate of the destination rectangle area. 
+     * @param dy1 the Y top left corner coordinate of the destination rectangle area.
+     * @param dx2 the X bottom right corner coordinate of the destination rectangle area.
+     * @param dy2 the Y bottom right corner coordinate of the destination rectangle area.
+     * @param sx1 the X top left corner coordinate of the area to be drawn within the source image.
+     * @param sy1 the Y top left corner coordinate of the area to be drawn within the source image.
+     * @param sx2 the X bottom right corner coordinate of the area to be drawn within the source image.
+     * @param sy2 the Y bottom right corner coordinate of the area to be drawn within the source image.
+     * @param bgcolor the background color.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer);
+
+    /**
+     * Scales the specified area of the specified image to fit in the rectangle area 
+     * defined by its corners coordinates and draws the sub-image. The sub-image 
+     * to be drawn is defined by its top left 
+     * corner coordinates (sx1, sy1) and bottom right corner coordinates (sx2, sy2)
+     * computed with respect to the origin (top left corner) of the source image.
+     * The image loading process notifies specified Image Observer. 
+     * This method returns true if the image
+     * has loaded, overwise it returns false. 
+     * 
+     * @param img the image which will be drawn.
+     * @param dx1 the X top left corner coordinate of the destination rectangle area. 
+     * @param dy1 the Y top left corner coordinate of the destination rectangle area.
+     * @param dx2 the X bottom right corner coordinate of the destination rectangle area.
+     * @param dy2 the Y bottom right corner coordinate of the destination rectangle area.
+     * @param sx1 the X top left corner coordinate of the area to be drawn within the source image.
+     * @param sy1 the Y top left corner coordinate of the area to be drawn within the source image.
+     * @param sx2 the X bottom right corner coordinate of the area to be drawn within the source image.
+     * @param sy2 the Y bottom right corner coordinate of the area to be drawn within the source image.
+     * @param observer the ImageObserver object which should be notified about image loading process.
+     * 
+     * @return true, if loading image is successful or image is null, overwise false.
+     */
+    public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer);
+    
+    /**
+     * Draws a line from the point (x1, y1) to the point (x2, y2). 
+     * This method draws the line with current color 
+     * which can be changed by setColor(Color c) method.
+     * 
+     * @param x1 the X coordinate of the first point.
+     * @param y1 the Y coordinate of the first point.
+     * @param x2 the X coordinate of the second point.
+     * @param y2 the Y coordinate of the second point.
+     */
+    public abstract void drawLine(int x1, int y1, int x2, int y2);
+
+    /**
+     * Draws the ouline of an oval to fit in the rectangle defined
+     * by the given width, height, and top left corner.
+     * 
+     * @param x the X top left corner oval coordinate
+     * @param y the Y top left corner oval coordinate
+     * @param width the oval width
+     * @param height the oval height
+     */
+    public abstract void drawOval(int x, int y, int width, int height);
+
+    /**
+     * Draws the outline of a polygon. The polygon vertices are defined by points 
+     * with xpoints[i], ypoints[i]  as coordinates. The polygon edges are the
+     * lines from the points with (xpoints[i-1], ypoints[i-1]) coordinates to   
+     * the points with (xpoints[i], ypoints[i]) coordinates, for 0 < i < npoints +1.
+     * 
+     * @param xpoints the array of X coordinates of the polygon vertices.
+     * @param ypoints the array of Y coordinates of the polygon vertices.
+     * @param npoints the number of polygon vertices/points.
+     */
+    public abstract void drawPolygon(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Draws a set of connected lines which are defined by the x and y coordinate arrays.  
+     * The polyline is closed if coordinates of the first point are the same as 
+     * coordinates of the last point.
+     * 
+     * @param xpoints the array of X point coordinates.
+     * @param ypoints the array of Y point coordinates.
+     * @param npoints the number of points.
+     */
+    public abstract void drawPolyline(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Draws the outline of a rectangle with round corners.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of the rectangle.
+     * @param height the height of the rectangle.
+     * @param arcWidth the arc width for the corners.
+     * @param arcHeight the arc height for the corners.
+     */
+    public abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
+
+    /**
+     * Draws a text defined by an iterator. The iterator should specify the font 
+     * for every character. 
+     *  
+     * @param iterator the iterator.
+     * @param x the X coordinate of the firt character.
+     * @param y the Y coordinate of the first character.
+     */
+    public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);
+
+    /**
+     * Draws a text defined by a string. This method draws the text with current
+     * font and color.
+     * 
+     * @param str the string. 
+     * @param x the X coordinate of the firt character.
+     * @param y the Y coordinate of the first character.
+     */
+    public abstract void drawString(String str, int x, int y);
+
+    /**
+     * Fills the arc covering the rectangle and using the current color. 
+     * The rectangle is defined by the origin point (X, Y) and dimentions (width and height). 
+     * The arc center is the the center of specified rectangle. 
+     * The angle origin is at the 3 o'clock position, and a positive angle gives  
+     * counter-clockwise rotation, a negative angle gives clockwise rotation.
+     *  
+     * @param x the X origin coordinate of the rectangle which scales the arc. 
+     * @param y the Y origin coordinate of the rectangle which scales the arc.
+     * @param width the width of the rectangle which scales the arc.
+     * @param height the height of the rectangle which scales the arc.
+     * @param sa start angle - the origin angle of arc.
+     * @param ea arc angle - the angular arc value relative to the start angle. 
+     */
+    public abstract void fillArc(int x, int y, int width, int height, int sa, int ea);
+
+    /**
+     * Fills an oval with the current color where the oval is defined by the 
+     * bounding rectangle with the given width, height, and top left corner.
+     * 
+     * @param x the X top left corner oval coordinate.
+     * @param y the Y top left corner oval coordinate.
+     * @param width the oval width.
+     * @param height the oval height.
+     */
+    public abstract void fillOval(int x, int y, int width, int height);
+
+    /**
+     * Fills a polygon with the current color. The polygon vertices are defined by the points 
+     * with xpoints[i], ypoints[i] as coordinates. The polygon edges are the
+     * lines from the points with (xpoints[i-1], ypoints[i-1]) coordinates to   
+     * the points with (xpoints[i], ypoints[i]) coordinates, for 0 < i < npoints +1.
+     * 
+     * @param xpoints the array of X coordinates of the polygon vertices.
+     * @param ypoints the array of Y coordinates of the polygon vertices.
+     * @param npoints the number of polygon vertices/points.
+     */
+    public abstract void fillPolygon(int[] xpoints, int[] ypoints, int npoints);
+
+    /**
+     * Fills a rectangle with the current color. 
+     * The rectangle is defined by its width and length and top left corner coordinates.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     */
+    public abstract void fillRect(int x, int y, int width, int height);
+
+    /**
+     * Fills a round cornered rectangle with the current color.
+     * 
+     * @param x the X coordinate of the top left corner of the bounding rectangle.
+     * @param y the Y coordinate of the top left corner of the bounding rectangle.
+     * @param width the width of the bounding rectangle.
+     * @param height the height of the bounding rectangle.
+     * @param arcWidth the arc width at the corners.
+     * @param arcHeight the arc height at the corners.
+     */
+    public abstract void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
+
+    /**
+     * Gets the clipping area.
+     * <br> <br>
+     *  
+     * @return a Shape object of the clipping area or null if it is not set.
+     */
+    public abstract Shape getClip();
+
+    /**
+     * Gets the bounds of the current clipping area as a rectangle.
+     *  
+     * @return a Rectangle object which represents the bounds of the current clipping area. 
+     */
+    public abstract Rectangle getClipBounds();
+
+    /**
+     * Gets the current color of Graphics.
+     * 
+     * @return the current color.
+     */
+    public abstract Color getColor();
+
+    /**
+     * Gets the current font of Graphics.
+     * 
+     * @return the current font.
+     */
+    public abstract Font getFont();
+
+    /**
+     * Gets the font metrics of the specified font. 
+     * The font metrics object contains information about the rendering of a particular font.
+     * 
+     * @param font the specified font
+     * 
+     * @return the font metrics for the specified font.
+     */
+    public abstract FontMetrics getFontMetrics(Font font);
+
+    /**
+     * Sets the new clipping area specified by rectangle. The new clipping area 
+     * doesn't depend on the window's visibility. Rendering operations can't be performed 
+     * outside new clipping area.
+     * 
+     * @param x the X coordinate of the new clipping rectangle.
+     * @param y the Y coordinate of the new clipping rectangle.
+     * @param width the width of the new clipping rectangle.
+     * @param height the height of the new clipping rectangle.
+     */
+    public abstract void setClip(int x, int y, int width, int height);
+
+    /**
+     * Sets the new clipping area to be the area specified by Shape object. 
+     * The new clipping area doesn't depend on the window's visibility. 
+     * Rendering operations can't be performed outside new clipping area.
+     * 
+     * @param clip a Shape object which representes new clipping area.
+     */
+    public abstract void setClip(Shape clip);
+
+    /**
+     * Sets the current Graphics color. All rendering operations with this Graphics
+     * will use this color.
+     * 
+     * @param c the new color.
+     */
+    public abstract void setColor(Color c);
+
+    /**
+     * Sets the current Graphics font. All rendering operations with this Graphics
+     * will use this font.
+     * 
+     * @param font the new font.
+     */
+    public abstract void setFont(Font font);
+
+    /**
+     * Sets the paint mode for the Graphics which overwrites all rendering 
+     * operations with the current color.
+     *  
+     */
+    public abstract void setPaintMode();
+
+    /**
+     * Sets the XOR mode for the Graphics which changes a pixel from
+     * the current color to the specified XOR color.
+     * <br> <br>
+     * 
+     * @param color the new XOR mode
+     */
+    public abstract void setXORMode(Color color);
+
+    /**
+     * Translates the origin of Graphics current coordinate system 
+     * to the point with X, Y coordinates in the current coordinate system.
+     * All rendering operation in this Graphics will be related to the new origin.
+     * 
+     * @param x the X coordinate of the origin
+     * @param y the Y coordinate of the origin
+     */
+    public abstract void translate(int x, int y);
+}
diff --git a/awt/java/awt/Graphics2D.java b/awt/java/awt/Graphics2D.java
new file mode 100644
index 0000000..2ff5e0c
--- /dev/null
+++ b/awt/java/awt/Graphics2D.java
@@ -0,0 +1,456 @@
+/*
+ *  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 java.awt;
+
+import java.awt.font.GlyphVector;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ImageObserver;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderableImage;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+/**
+ * The Graphics2D class extends Graphics class and provides more capabilities
+ * for rendering text, images, shapes. This provides methods to peform 
+ * transformation of coordinate system, color management, and text layout. 
+ * The following attributes exist for rendering:
+ * <ul>
+ * <li>Color - current Graphics2D color;</li>
+ * <li>Font - current Graphics2D font;</li>
+ * <li>Stroke - pen with a width of 1 pixel;</li>  
+ * <li>Transform - current Graphics2D Transformation;</li>
+ * <li>Composite - alpha compositing rules for combining source and destination colors.</li>
+ * </ul> 
+ */
+public abstract class Graphics2D extends Graphics {
+    
+    /**
+     * Instantiates a new Graphics2D object. This constructor should never be
+     * called directly.
+     */
+    protected Graphics2D() {
+        super();
+    }
+
+    /**
+     * Adds preferences for the rendering algorithms. The preferences
+     * are arbitrary and specified by Map objects. All specified by Map object
+     * preferencies can be modified. 
+     * 
+     * @param hints the rendering hints.
+     */
+    public abstract void addRenderingHints(Map<?, ?> hints);
+
+    /**
+     * Intersects the current clipping area with the specified Shape 
+     * and the result becomes a new clipping area. 
+     * If current clipping area is not defined, the Shape 
+     * becomes the new clipping area. No rendering operations 
+     * are allowed outside the clipping area.  
+     * 
+     * @param s the specified Shape object which will be intersected 
+     * with current clipping area.
+     */
+    public abstract void clip(Shape s);
+
+    /**
+     * Draws the outline of the specified Shape.
+     * 
+     * @param s the Shape which ouline is drawn.
+     */
+    public abstract void draw(Shape s);
+
+    /**
+     * Draws the specified GlyphVector object's text at the point x, y. 
+     * 
+     * @param g the GlyphVector object to be drawn.
+     * @param x the X position where the GlyphVector's text should 
+     * be rendered.  
+     * @param y the Y position where the GlyphVector's text should 
+     * be rendered.
+     */
+    public abstract void drawGlyphVector(GlyphVector g, float x, float y);
+
+    /**
+     * Draws the BufferedImage -- modified according to the operation
+     * BufferedImageOp -- at the point x, y.
+     * 
+     * @param img the BufferedImage to be rendered.
+     * @param op the filter to be applied to the image before rendering. 
+     * @param x the X coordinate of the point where the image's upper left corner
+     * will be placed.
+     * @param y the Y coordinate of the point where the image's upper left corner
+     * will be placed.
+     */
+    public abstract void drawImage(BufferedImage img, BufferedImageOp op, int x, int y);
+
+    /**
+     * Draws BufferedImage transformed from image space into user space 
+     * according to the AffineTransform xform and notifies the ImageObserver.
+     *  
+     * @param img the BufferedImage to be rendered.
+     * @param xform the affine transformation from the image to the user space.
+     * @param obs the ImageObserver to be notified about the image conversion.
+     * 
+     * @return true, if the image is successfully loaded and rendered, 
+     * or it's null, otherwise false.
+     */
+    public abstract boolean drawImage(Image img, AffineTransform xform, ImageObserver obs);
+
+    /**
+     * Draws a RenderableImage which is transformed from image space into user 
+     * according to the AffineTransform xform.
+     *  
+     * @param img the RenderableImage to be rendered.
+     * @param xform the affine transformation from image to user space.
+     */
+    public abstract void drawRenderableImage(RenderableImage img, AffineTransform xform);
+
+    /**
+     * Draws a RenderedImage which is transformed from image space into user 
+     * according to the AffineTransform xform.
+     *  
+     * @param img the RenderedImage to be rendered.
+     * @param xform the affine transformation from image to user space.
+     */
+    public abstract void drawRenderedImage(RenderedImage img, AffineTransform xform);
+
+    /**
+     * Draws the string specified by the AttributedCharacterIterator. 
+     * The first character's position is specified by the X, Y parameters.   
+     * 
+     * @param iterator whose text is drawn.
+     * @param x the X position where the first character is drawn. 
+     * @param y the Y position where the first character is drawn.
+     */
+    public abstract void drawString(AttributedCharacterIterator iterator, float x, float y);
+
+    /**
+     * Draws the string specified by the AttributedCharacterIterator. 
+     * The first character's position is specified by the X, Y parameters.   
+     * 
+     * @param iterator whose text is drawn.
+     * @param x the X position where the first character is drawn. 
+     * @param y the Y position where the first character is drawn.
+     * 
+     * @see java.awt.Graphics#drawString(AttributedCharacterIterator, int, int)
+     */
+    @Override
+    public abstract void drawString(AttributedCharacterIterator iterator, int x, int y);
+
+    /**
+     * Draws the String whose the first character position is specified 
+     * by the parameters X, Y.   
+     * 
+     * @param s the String to be drawn.
+     * @param x the X position of the first character. 
+     * @param y the Y position of the first character.
+     */
+    public abstract void drawString(String s, float x, float y);
+
+    /**
+     * Draws the String whose the first character coordinates are specified 
+     * by the parameters X, Y.   
+     * 
+     * @param str the String to be drawn.
+     * @param x the X coordinate of the first character. 
+     * @param y the Y coordinate of the first character.
+     * 
+     * @see java.awt.Graphics#drawString(String, int, int)
+     */
+    @Override
+    public abstract void drawString(String str, int x, int y);
+
+    /**
+     * Fills the interior of the specified Shape.
+     * 
+     * @param s the Shape to be filled.
+     */
+    public abstract void fill(Shape s);
+
+    /**
+     * Gets the background color.
+     * 
+     * @return the current background color.
+     */
+    public abstract Color getBackground();
+
+    /**
+     * Gets the current composite of the Graphics2D.
+     * 
+     * @return the current composite which specifies the compositing style.
+     */
+    public abstract Composite getComposite();
+
+    /**
+     * Gets the device configuration.
+     * 
+     * @return the device configuration
+     */
+    public abstract GraphicsConfiguration getDeviceConfiguration();
+
+    /**
+     * Gets the rendering context of the Font.
+     * 
+     * @return the FontRenderContext.
+     */
+    public abstract FontRenderContext getFontRenderContext();
+
+    /**
+     * Gets the current Paint of Graphics2D.
+     * 
+     * @return the current Paint of Graphics2D.
+     */
+    public abstract Paint getPaint();
+
+    /**
+     * Gets the value of single preference for specified key. 
+     * 
+     * @param key the specified key of the rendering hint.
+     * 
+     * @return the value of rendering hint for specified key.
+     */
+    public abstract Object getRenderingHint(RenderingHints.Key key);
+
+    /**
+     * Gets the set of the rendering preferences as a collection of 
+     * key/value pairs.
+     * 
+     * @return the RenderingHints which contains the rendering preferences.
+     */
+    public abstract RenderingHints getRenderingHints();
+
+    /**
+     * Gets current stroke of the Graphics2D.
+     * 
+     * @return current stroke of the Graphics2D.
+     */
+    public abstract Stroke getStroke();
+
+    /**
+     * Gets current affine transform of the Graphics2D.
+     * 
+     * @return current AffineTransform of the Graphics2D.
+     */
+    public abstract AffineTransform getTransform();
+
+    /**
+     * Determines wether or not the specified Shape intersects the specified 
+     * Rectangle. If the onStroke parameter is true, this method 
+     * checks whether or not the specified Shape outline intersects the specified 
+     * Rectangle, otherwise this method checks whether or not the specified 
+     * Shape's interior intersects the specified Rectangle.   
+     * 
+     * @param rect the specified Rectangle.
+     * @param s the Shape to check for intersection.
+     * @param onStroke the parameter determines whether or not this method checks
+     * for intersection of the Shape outline or of the Shape interior with 
+     * the Rectangle. 
+     * 
+     * @return true, if there is a hit, otherwise false.
+     */
+    public abstract boolean hit(Rectangle rect, Shape s, boolean onStroke);
+
+    /**
+     * Performs a rotation transform relative to current Graphics2D Transform.
+     * The coordinate system is rotated by the specified angle in radians relative to 
+     * current origin.
+     * 
+     * @param theta the angle of rotation in radians.
+     */
+    public abstract void rotate(double theta);
+
+    /**
+     * Performs a translated rotation transform relative to current Graphics2D 
+     * Transform. The coordinate system is rotated by the specified angle in radians 
+     * relative to current origin and then moved to point (x, y).
+     * 
+     * Is this right?
+     * 
+     * @param theta the angle of rotation in radians.
+     * @param x the X coordinate.
+     * @param y the Y coordinate. 
+     */
+    public abstract void rotate(double theta, double x, double y);
+
+    /**
+     * Performs a linear scale transform relative to current Graphics2D Transform.
+     * The coordinate system is rescaled vertically and horizontally 
+     * by the specified parameters.
+     * 
+     * @param sx the scaling factor by which the X coordinate is multiplied.   
+     * @param sy the scaling factor by which the Y coordinate is multiplied.   
+     */
+    public abstract void scale(double sx, double sy);
+
+    /**
+     * Sets a new background color for clearing rectangular areas. 
+     * The clearRect method uses the current background color. 
+     * 
+     * @param color the new background color.
+     */
+    public abstract void setBackground(Color color);
+
+    /**
+     * Sets the current composite for Graphics2D. 
+     * 
+     * @param comp the Composite object.
+     */
+    public abstract void setComposite(Composite comp);
+
+    /**
+     * Sets the paint for Graphics2D.
+     * 
+     * @param paint the Paint object.
+     */
+    public abstract void setPaint(Paint paint);
+
+    /**
+     * Sets a key-value pair in the current RenderingHints map.
+     * 
+     * @param key the key of the rendering hint to set.
+     * @param value the value to set for the rendering hint.
+     */
+    public abstract void setRenderingHint(RenderingHints.Key key, Object value);
+
+    /**
+     * Replaces the current rendering hints with the specified rendering preferences.
+     * 
+     * @param hints the new Map of rendering hints.
+     */
+    public abstract void setRenderingHints(Map<?, ?> hints);
+
+    /**
+     * Sets the stroke for the Graphics2D.
+     * 
+     * @param s the Stroke object.
+     */
+    public abstract void setStroke(Stroke s);
+
+    /**
+     * Overwrite the current Transform of the Graphics2D. The specified Transform 
+     * should be received from the getTransform() method and should be used 
+     * only for restoring the original Graphics2D transform after calling
+     * draw or fill methods. 
+     * 
+     * @param Tx the specified Transform.
+     */
+    public abstract void setTransform(AffineTransform Tx);
+
+    /**
+     * Performs a shear transform relative to current Graphics2D Transform.
+     * The coordinate system is shifted by the specified multipliers relative to 
+     * current position.
+     * 
+     * @param shx the multiplier by which the X coordinates shift position
+     * along X axis as a function of Y coordinates.   
+     * @param shy the multiplier by which the Y coordinates shift position
+     * along Y axis as a function of X coordinates.   
+     */
+    public abstract void shear(double shx, double shy);
+
+    /**
+     * Concatenates the AffineTransform object with current Transform 
+     * of this Graphics2D. The transforms are applied in reverse order
+     * with the last specified transform applied first and the next
+     * transformation applied to the result of previous transformation. 
+     * More precisely, if Cx is the current Graphics2D transform, the 
+     * transform method's result with Tx as the parameter
+     * is the transformation Rx, where Rx(p) = Cx(Tx(p)), for p - a point
+     * in current coordinate system. Rx becomes the current Transform   
+     * for this Graphics2D.
+     * 
+     * @param Tx the AffineTransform object to be concatenated with 
+     * current Transform.
+     */
+    public abstract void transform(AffineTransform Tx);
+
+    /**
+     * Performs a translate transform relative to current Graphics2D Transform.
+     * The coordinate system is moved by the specified distance relative 
+     * to current position.
+     * 
+     * @param tx the translation distance along the X axis.
+     * @param ty the translation distance along the Y axis.
+     */
+    public abstract void translate(double tx, double ty);
+
+    /**
+     * Moves the origin Graphics2D Transform to the point with x, y
+     * coordinates in current coordinate system. The new origin of coordinate 
+     * system is moved to the (x, y) point accordingly. All rendering and 
+     * transform operations are performed relative to this new origin.
+     * 
+     * @param x the X coordinate.
+     * @param y the Y coordinate. 
+     * 
+     * @see java.awt.Graphics#translate(int, int)
+     */
+    @Override
+    public abstract void translate(int x, int y);
+
+    /**
+     * Fills a 3D rectangle with the current color. 
+     * The rectangle is specified by its width, height, and top left corner 
+     * coordinates.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     * 
+     * @see java.awt.Graphics#fill3DRect(int, int, int, int, boolean)
+     */
+    @Override
+    public void fill3DRect(int x, int y, int width, int height, boolean raised) {
+        // According to the spec, color should be used instead of paint,
+        // so Graphics.fill3DRect resets paint and
+        // it should be restored after the call
+        Paint savedPaint = getPaint();
+        super.fill3DRect(x, y, width, height, raised);
+        setPaint(savedPaint);
+    }
+
+    /**
+     * Draws the higlighted outline of a rectangle.
+     * 
+     * @param x the X coordinate of the rectangle's top left corner.
+     * @param y the Y coordinate of the rectangle's top left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle.
+     * @param raised a boolean value that determines whether the rectangle 
+     * is drawn as raised or indented.
+     *       
+     * @see java.awt.Graphics#draw3DRect(int, int, int, int, boolean)
+     */
+    @Override
+    public void draw3DRect(int x, int y, int width, int height, boolean raised) {
+        // According to the spec, color should be used instead of paint,
+        // so Graphics.draw3DRect resets paint and
+        // it should be restored after the call
+        Paint savedPaint = getPaint();
+        super.draw3DRect(x, y, width, height, raised);
+        setPaint(savedPaint);
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/GraphicsConfiguration.java b/awt/java/awt/GraphicsConfiguration.java
new file mode 100644
index 0000000..8bec253
--- /dev/null
+++ b/awt/java/awt/GraphicsConfiguration.java
@@ -0,0 +1,217 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.VolatileImage;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicsConfiguration class contains the characteristics of graphics
+ * devices such as a printer or monitor, and represents device's capabilities
+ * and modes. Many GraphicsConfiguration objects can be associated with
+ * single graphics device.
+ */
+public abstract class GraphicsConfiguration {
+   
+   /**
+     * Constructor could not be used directly and should be obtained in 
+     * extended classes. 
+    */
+
+    protected GraphicsConfiguration() {
+    }
+
+
+   /**
+    * Creates BufferedImage image object with a data layout and color model 
+    * compatible with this GraphicsConfiguration with specified width 
+    * and height parameters.
+    * 
+    * @param width the width of BufferedImage.
+    * @param height the height of BufferedImage.
+    * 
+    * @return the BufferedImage object with specified width and height 
+    * parameters.
+    */
+    public abstract BufferedImage createCompatibleImage(int width, int height);
+
+    /**
+     * Creates a BufferedImage that has the specified width, height,
+     * transparency and has a data layout and color model compatible with this 
+     * GraphicsConfiguration. 
+     * 
+     * @param width the width of image.
+     * @param height the height  of image.
+     * @param transparency the transparency mode.
+     * 
+     * @return the BufferedImage object.
+     */
+    public abstract BufferedImage createCompatibleImage(int width, int height, int transparency);
+
+    /**
+     * Creates a VolatileImage that has the specified width and height 
+     * and has a data layout and color model compatible with this 
+     * GraphicsConfiguration. 
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * 
+     * @return the VolatileImage object.
+     */
+    public abstract VolatileImage createCompatibleVolatileImage(int width, int height);
+
+    /**
+     * Creates a VolatileImage that supports the specified width, height,
+     * transparency and has a data layout and color model compatible with this 
+     * GraphicsConfiguration. 
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * @param transparency the transparency mode.
+     * 
+     * @return the VolatileImage object.
+     */
+    public abstract VolatileImage createCompatibleVolatileImage(int width, int height, int transparency);
+
+    /**
+     * Gets the bounds of area covered by the GraphicsConfiguration in the
+     * device coordinates space.
+     * 
+     * @return the Rectangle of GraphicsConfiguration's bounds.
+     */
+    public abstract Rectangle getBounds();
+
+    /**
+     * Gets the ColorModel of the GraphicsConfiguration.
+     * 
+     * @return the ColorModel object of the GraphicsConfiguration.
+     */
+    public abstract ColorModel getColorModel();
+
+    /**
+     * Gets the ColorModel of the GraphicsConfiguration which 
+     * supports specified Transparency.
+     * 
+     * @param transparency the Transparency mode: OPAQUE, BITMASK, or
+     * TRANSLUCENT.
+     * 
+     * @return the ColorModel of the GraphicsConfiguration which 
+     * supports specified Transparency.
+     */
+    public abstract ColorModel getColorModel(int transparency);
+
+    /**
+     * Gets the default AffineTransform of the GraphicsConfiguration.
+     * This method translates user coordinates to device coordinates.
+     * 
+     * @return the default AffineTransform of the GraphicsConfiguration.
+     */
+    public abstract AffineTransform getDefaultTransform();
+
+    /**
+     * Gets the GraphicsDevice of the GraphicsConfiguration.
+     * 
+     * @return the GraphicsDevice of the GraphicsConfiguration.
+     */
+    public abstract GraphicsDevice getDevice();
+
+    /**
+     * Gets the normalizing AffineTransform of the GraphicsConfiguration.
+     * 
+     * @return the normalizing AffineTransform of the GraphicsConfiguration.
+     */
+    public abstract AffineTransform getNormalizingTransform();
+
+
+    /**
+     * Creates VolatileImage with specified width, height, ImageCapabilities;
+     * a data layout and color model compatible with this GraphicsConfiguration. 
+     *  
+     * @param width the width of image.
+     * @param height the height of image.
+     * @param caps the ImageCapabilities object.
+     * 
+     * @return the VolatileImage which data layout and color model compatible 
+     * with this GraphicsConfiguration. 
+     * 
+     * @throws AWTException if ImageCapabilities is not supported by the
+     * GraphicsConfiguration.
+     */
+    public VolatileImage createCompatibleVolatileImage(int width, int height,
+            ImageCapabilities caps) throws AWTException {
+        VolatileImage res = createCompatibleVolatileImage(width, height);
+        if (!res.getCapabilities().equals(caps)) {
+            // awt.14A=Can not create VolatileImage with specified capabilities
+            throw new AWTException(Messages.getString("awt.14A")); //$NON-NLS-1$
+        }
+        return res;
+    }
+
+    /**
+     * Creates a VolatileImage with specified width, height, transparency 
+     * and ImageCapabilities; a data layout and color model compatible with 
+     * this GraphicsConfiguration.
+     * 
+     * @param width the width of image.
+     * @param height the height of image.
+     * @param caps the ImageCapabilities object.
+     * @param transparency the Transparency mode: OPAQUE, BITMASK, or
+     * TRANSLUCENT.
+     * 
+     * @return the VolatileImage which data layout and color model compatible 
+     * with this GraphicsConfiguration. 
+     * 
+     * @throws AWTException if ImageCapabilities is not supported by the
+     * GraphicsConfiguration.
+     */
+    public VolatileImage createCompatibleVolatileImage(int width, int height,
+            ImageCapabilities caps, int transparency) throws AWTException {
+        VolatileImage res = createCompatibleVolatileImage(width, height, transparency);
+        if (!res.getCapabilities().equals(caps)) {
+            // awt.14A=Can not create VolatileImage with specified capabilities
+            throw new AWTException(Messages.getString("awt.14A")); //$NON-NLS-1$
+        }
+        return res;
+    }
+
+    /**
+     * Gets the buffering capabilities of the GraphicsConfiguration.
+     * 
+     * @return the BufferCapabilities object. 
+     */
+    public BufferCapabilities getBufferCapabilities() {
+        return new BufferCapabilities(new ImageCapabilities(false), new ImageCapabilities(false),
+                BufferCapabilities.FlipContents.UNDEFINED);
+    }
+
+    /**
+     * Gets the image capabilities of the GraphicsConfiguration.
+     * 
+     * @return the ImageCapabilities object.
+     */
+    public ImageCapabilities getImageCapabilities() {
+        return new ImageCapabilities(false);
+    }
+}
diff --git a/awt/java/awt/GraphicsDevice.java b/awt/java/awt/GraphicsDevice.java
new file mode 100644
index 0000000..8cf700a
--- /dev/null
+++ b/awt/java/awt/GraphicsDevice.java
@@ -0,0 +1,199 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicsDevice class describes the graphics devices (such as screens 
+ * or printers) which are available in a particular graphics environment. 
+ * Many GraphicsDevice instances can be associated with a single
+ * GraphicsEnvironment. Each GraphicsDevice has one or more GraphicsConfiguration
+ * objects which specify the different configurations and modes of GraphicsDevice.
+ */
+public abstract class GraphicsDevice {
+    
+    /** The display mode. */
+    private DisplayMode displayMode;
+
+    //???AWT
+//    private Window fullScreenWindow = null;
+
+   /** The Constant TYPE_IMAGE_BUFFER indicates a image buffer device. */
+
+    public static final int TYPE_IMAGE_BUFFER = 2;
+
+    /** The Constant TYPE_PRINTER indicates a printer device. */
+    public static final int TYPE_PRINTER = 1;
+
+    /** The Constant TYPE_RASTER_SCREEN indicates a raster screen device. */
+    public static final int TYPE_RASTER_SCREEN = 0;
+
+   /**
+    * Constructor is not to be used directly as this class is abstract. 
+    */
+    protected GraphicsDevice() {
+        displayMode = new DisplayMode(0, 0, DisplayMode.BIT_DEPTH_MULTI, DisplayMode.REFRESH_RATE_UNKNOWN);
+    }
+
+
+   /**
+    * Returns an array of GraphicsConfiguration objects associated
+    * with the GraphicsDevice.  
+    * 
+    * @return an array of GraphicsConfiguration objects associated
+    * with the GraphicsDevice.
+    */
+    public abstract GraphicsConfiguration[] getConfigurations();
+
+    /**
+     * Gets the default configuration for the GraphicsDevice.
+     * 
+     * @return the default GraphicsConfiguration object for the GraphicsDevice.
+     */
+    public abstract GraphicsConfiguration getDefaultConfiguration();
+
+    /**
+     * Gets the String identifier which associated with the GraphicsDevice in 
+     * the GraphicsEnvironment.
+     * 
+     * @return the String identifier of the GraphicsDevice in 
+     * the GraphicsEnvironment.
+     */
+    public abstract String getIDstring();
+
+    /**
+     * Gets the type of this GraphicsDevice: 
+     * TYPE_IMAGE_BUFFER, TYPE_PRINTER or TYPE_RASTER_SCREEN.
+     * 
+     * @return the type of this GraphicsDevice: TYPE_IMAGE_BUFFER, 
+     * TYPE_PRINTER or TYPE_RASTER_SCREEN.
+     */
+    public abstract int getType();
+
+
+
+   /**
+	* Returns the number of bytes available in accelerated 
+	* memory on this device. 
+    * 
+    * @return the number of bytes available accelerated memory.
+    */
+    public int getAvailableAcceleratedMemory() {
+        return 0;
+    }
+
+    /* ???AWT
+    public GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate gct) {
+        return gct.getBestConfiguration(getConfigurations());
+    }
+    */
+    
+    /**
+     * Gets the current display mode of the GraphicsDevice.
+     * 
+     * @return the current display mode of the GraphicsDevice.
+     */
+    public DisplayMode getDisplayMode() {
+        return displayMode;
+    }
+
+    /**
+     * Gets an array of display modes available in this GraphicsDevice.
+     * 
+     * @return an array of display modes available in this GraphicsDevice.
+     */
+    public DisplayMode[] getDisplayModes() {
+        DisplayMode []dms = {displayMode};
+        return  dms;
+    }
+
+    /* ???AWT
+    public Window getFullScreenWindow() {
+        return fullScreenWindow;
+    }
+    */
+    
+    /**
+     * Returns true if this GraphicsDevice supports low-level 
+     * display changes.
+     * 
+     * @return true, if this GraphicsDevice supports low-level 
+     * display changes; false otherwise.
+     */
+    public boolean isDisplayChangeSupported() {
+        return false;
+    }
+
+    /**
+     * Returns true if this GraphicsDevice supports full screen
+     * mode.
+     * 
+     * @return true, if this GraphicsDevice supports full screen
+     * mode; otherwise false.
+     */
+    public boolean isFullScreenSupported() {
+        return false;
+    }
+    //an array of display modes available in this GraphicsDevice.
+    
+    /**
+     * Sets the display mode of this GraphicsDevice.
+     * 
+     * @param dm the new display mode of this GraphicsDevice. 
+     */
+    public void setDisplayMode(DisplayMode dm) {
+        if (!isDisplayChangeSupported()) {
+            // awt.122=Does not support display mode changes
+            throw new UnsupportedOperationException(Messages.getString("awt.122")); //$NON-NLS-1$
+        }
+
+        DisplayMode []dms = getDisplayModes();
+        for (DisplayMode element : dms) {
+            if (element.equals(dm)) {
+                displayMode = dm;
+                return;
+            }
+        }
+        // awt.123=Unsupported display mode: {0}
+        throw new IllegalArgumentException(Messages.getString("awt.123", dm)); //$NON-NLS-1$
+    }
+
+    /* ???AWT
+    public void setFullScreenWindow(Window w) {
+        if (w == null) {
+            fullScreenWindow = null;
+            return;
+        }
+
+        fullScreenWindow = w;
+
+        if (isFullScreenSupported()) {
+            w.enableInputMethods(false);
+        } else {
+            w.setSize(displayMode.getWidth(), displayMode.getHeight());
+            w.setLocation(0, 0);
+        }
+        w.setVisible(true);
+        w.setAlwaysOnTop(true);
+    }
+    */
+}
diff --git a/awt/java/awt/GraphicsEnvironment.java b/awt/java/awt/GraphicsEnvironment.java
new file mode 100644
index 0000000..3b14f55
--- /dev/null
+++ b/awt/java/awt/GraphicsEnvironment.java
@@ -0,0 +1,209 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt;
+
+import java.awt.image.BufferedImage;
+import java.util.Locale;
+
+import org.apache.harmony.awt.ContextStorage;
+import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
+
+/**
+ * The GraphicsEnvironment class defines a collection of GraphicsDevice 
+ * objects and Font objects which are available for Java application on
+ * current platform.
+ */
+public abstract class GraphicsEnvironment {
+    
+    /**
+     * Constructor could not be used directly and should be obtained in 
+     * extended classes. 
+     */
+    protected GraphicsEnvironment() {}
+
+    /**
+     * Gets the local GraphicsEnvironment.
+     * 
+     * @return the local GraphicsEnvironment.
+     */
+    public static GraphicsEnvironment getLocalGraphicsEnvironment() {
+        synchronized(ContextStorage.getContextLock()) {
+            if (ContextStorage.getGraphicsEnvironment() == null) {
+                if (isHeadless()) {                    
+                    ContextStorage.setGraphicsEnvironment(new HeadlessGraphicsEnvironment());                    
+                } else {
+                    CommonGraphics2DFactory g2df =
+                            (CommonGraphics2DFactory) Toolkit.getDefaultToolkit().getGraphicsFactory();
+                    
+                    ContextStorage.setGraphicsEnvironment( 
+                            g2df.createGraphicsEnvironment(ContextStorage.getWindowFactory())
+                    );
+                }
+            }
+
+            return ContextStorage.getGraphicsEnvironment();
+        }
+    }
+
+    /**
+     * Returns whether or not a display, keyboard, and mouse are supported 
+     * in this graphics environment.
+     * 
+     * @return true, if HeadlessException will be thrown from areas of 
+     * the graphics environment that are dependent on a display, keyboard, 
+     * or mouse; false otherwise.
+     */
+    public boolean isHeadlessInstance() {
+        return false;
+    }
+
+    /**
+     * Checks whether or not a display, keyboard, and mouse are supported 
+     * in this environment. 
+     * 
+     * @return true, if a HeadlessException is thrown from areas of 
+     * the Toolkit and GraphicsEnvironment that are dependent on 
+     * a display, keyboard, or mouse; false otherwise.
+     */
+    public static boolean isHeadless() {
+        return "true".equals(System.getProperty("java.awt.headless"));
+    }
+
+    /**
+     * Gets the maximum bounds of system centered windows.
+     * 
+     * @return the maximum bounds of system centered windows.
+     * 
+     * @throws HeadlessException if isHeadless() method returns true.
+     */
+    public Rectangle getMaximumWindowBounds() throws HeadlessException {
+        return getDefaultScreenDevice().getDefaultConfiguration().getBounds();
+    }
+
+    /**
+     * Gets the Point which should defines the center of system window.
+     * 
+     * @return the Point where the system window should be centered.
+     * 
+     * @throws HeadlessException if isHeadless() method returns true.
+     */
+    public Point getCenterPoint() throws HeadlessException {
+        Rectangle mwb = getMaximumWindowBounds();
+        return new Point(mwb.width >> 1, mwb.height >> 1);
+    }
+
+    /**
+     * Indicates that the primary font should be used. 
+     * Primary font is specified by initial system locale or default encoding).
+     * 
+     */
+    public void preferLocaleFonts() {
+        // Note: API specification says following:
+        // "The actual change in font rendering behavior resulting
+        // from a call to this method is implementation dependent;
+        // it may have no effect at all." So, doing nothing is an
+        // acceptable behavior for this method.
+
+        // For now FontManager uses 1.4 font.properties scheme for font mapping, so
+        // this method doesn't make any sense. The implementation of this method
+        // which will influence font mapping is postponed until
+        // 1.5 mapping scheme not implemented.
+
+        // todo - Implement non-default behavior with 1.5 font mapping scheme
+    }
+
+    /**
+     * Indicates that a proportional preference of the font should be used.
+     */
+    public void preferProportionalFonts() {
+        // Note: API specification says following:
+        // "The actual change in font rendering behavior resulting
+        // from a call to this method is implementation dependent;
+        // it may have no effect at all." So, doing nothing is an
+        // acceptable behavior for this method.
+
+        // For now FontManager uses 1.4 font.properties scheme for font mapping, so
+        // this method doesn't make any sense. The implementation of this method
+        // which will influence font mapping is postponed until
+        // 1.5 mapping scheme not implemented.
+
+        // todo - Implement non-default behavior with 1.5 font mapping scheme
+    }
+
+    /**
+     * Creates the Graphics2D object for rendering to the specified
+     * BufferedImage.
+     * 
+     * @param bufferedImage the BufferedImage object.
+     * 
+     * @return the Graphics2D object which allows to render to the specified 
+     * BufferedImage.
+     */
+    public abstract Graphics2D createGraphics(BufferedImage bufferedImage);
+
+    /**
+     * Gets the array of all available fonts instances in this 
+     * GraphicsEnviroments.
+     * 
+     * @return the array of all available fonts instances in this 
+     * GraphicsEnviroments.
+     */
+    public abstract Font[] getAllFonts();
+
+    /**
+     * Gets the array of all available font family names.
+     * 
+     * @return the array of all available font family names.
+     */
+    public abstract String[] getAvailableFontFamilyNames();
+
+    /**
+     * Gets the array of all available font family names for the specified
+     * locale.
+     * 
+     * @param locale the Locale object which represents geographical
+     * region. The default locale is used if locale is null.
+     * 
+     * @return the array of available font family names for the specified 
+     * locale.
+     */
+    public abstract String[] getAvailableFontFamilyNames(Locale locale);
+
+    /**
+     * Gets the default screen device as GraphicDevice object.
+     * 
+     * @return the GraphicDevice object which represents default screen device.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    public abstract GraphicsDevice getDefaultScreenDevice() throws HeadlessException;
+
+    /**
+     * Gets an array of all available screen devices.
+     * 
+     * @return the array of GraphicsDevice obgects which represents 
+     * all available screen devices.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    public abstract GraphicsDevice[] getScreenDevices() throws HeadlessException;
+}
diff --git a/awt/java/awt/HeadlessException.java b/awt/java/awt/HeadlessException.java
new file mode 100644
index 0000000..28e463b
--- /dev/null
+++ b/awt/java/awt/HeadlessException.java
@@ -0,0 +1,48 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The HeadlessException class provides notifications and error messages 
+ * when code that is dependent on a keyboard, display, or mouse is called 
+ * in an environment that does not support a keyboard, display, or mouse.
+ */
+public class HeadlessException extends UnsupportedOperationException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 167183644944358563L;
+
+    /**
+     * Instantiates a new headless exception.
+     */
+    public HeadlessException() {
+        super();
+    }
+
+    /**
+     * Instantiates a new headless exception with the specified message.
+     * 
+     * @param msg the String which represents error message. 
+     */
+    public HeadlessException(String msg) {
+        super(msg);
+    }
+}
diff --git a/awt/java/awt/HeadlessGraphicsEnvironment.java b/awt/java/awt/HeadlessGraphicsEnvironment.java
new file mode 100644
index 0000000..97f88d1
--- /dev/null
+++ b/awt/java/awt/HeadlessGraphicsEnvironment.java
@@ -0,0 +1,69 @@
+/*
+ *  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 java.awt;
+
+import java.awt.GraphicsDevice;
+import java.awt.HeadlessException;
+
+import org.apache.harmony.awt.gl.CommonGraphicsEnvironment;
+
+/**
+ * The HeadlessGraphicsEnvironment class is the CommonGraphicsEnvironment
+ * implementation to use in the case where the environment lacks display, 
+ * keyboard, and mouse support.
+ */
+public class HeadlessGraphicsEnvironment extends CommonGraphicsEnvironment {
+    
+    /**
+     * Returns whether or not a display, keyboard, and mouse are supported 
+     * in this graphics environment.
+     * 
+     * @return true, if HeadlessException will be thrown from areas of 
+     * the graphics environment that are dependent on a display, keyboard, 
+     * or mouse; false otherwise.
+     */
+    @Override
+    public boolean isHeadlessInstance() {
+        return true;
+    }
+    
+    /**
+     * Gets the default screen device as GraphicDevice object.
+     * 
+     * @return the GraphicDevice object which represents default screen device.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    @Override
+    public GraphicsDevice getDefaultScreenDevice() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    /**
+     * Gets an array of all available screen devices.
+     * 
+     * @return the array of GraphicsDevice objects which represents 
+     * all available screen devices.
+     * 
+     * @throws HeadlessException if isHeadless() returns true.
+     */
+    @Override
+    public GraphicsDevice[] getScreenDevices() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+}
diff --git a/awt/java/awt/HeadlessToolkit.java b/awt/java/awt/HeadlessToolkit.java
new file mode 100644
index 0000000..a7dd557
--- /dev/null
+++ b/awt/java/awt/HeadlessToolkit.java
@@ -0,0 +1,301 @@
+/*
+ *  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 java.awt;
+
+//???AWT
+//import java.awt.datatransfer.Clipboard;
+//import java.awt.dnd.DragGestureEvent;
+//import java.awt.dnd.DragGestureListener;
+//import java.awt.dnd.DragGestureRecognizer;
+//import java.awt.dnd.DragSource;
+//import java.awt.dnd.InvalidDnDOperationException;
+//import java.awt.dnd.peer.DragSourceContextPeer;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+//import java.awt.peer.*;
+//import java.beans.PropertyChangeSupport;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.harmony.awt.ComponentInternals;
+//import org.apache.harmony.awt.datatransfer.DTK;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+import org.apache.harmony.awt.wtk.WindowFactory;
+
+/**
+ * The HeadlessToolkit class is a subclass of ToolkitImpl to 
+ * be used for graphical environments that lack keyboard and 
+ * mouse capabilities.
+ */
+public final class HeadlessToolkit extends ToolkitImpl {
+    
+    //???AWT
+    /*
+    @Override
+    protected ButtonPeer createButton(Button a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    protected CheckboxPeer createCheckbox(Checkbox a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    protected ChoicePeer createChoice(Choice a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    public Cursor createCustomCursor(Image img, Point hotSpot, String name)
+    throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected DialogPeer createDialog(Dialog a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
+            Class<T> recognizerAbstractClass, DragSource ds, Component c, int srcActions,
+            DragGestureListener dgl) {
+        return null;
+    }
+
+    @Override
+    public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge)
+    throws InvalidDnDOperationException {
+        throw new InvalidDnDOperationException();
+    }
+
+    @Override
+    protected FileDialogPeer createFileDialog(FileDialog a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected FramePeer createFrame(Frame a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected LabelPeer createLabel(Label a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected ListPeer createList(List a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected MenuPeer createMenu(Menu a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected MenuBarPeer createMenuBar(MenuBar a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected MenuItemPeer createMenuItem(MenuItem a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected PopupMenuPeer createPopupMenu(PopupMenu a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected ScrollbarPeer createScrollbar(Scrollbar a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected ScrollPanePeer createScrollPane(ScrollPane a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected TextAreaPeer createTextArea(TextArea a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected TextFieldPeer createTextField(TextField a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected WindowPeer createWindow(Window a0) throws HeadlessException {
+        throw new HeadlessException();
+    }
+    */
+
+    @Override
+    public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public ColorModel getColorModel() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public GraphicsFactory getGraphicsFactory() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getMaximumCursorColors() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getMenuShortcutKeyMask() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    //???AWT
+    /*
+    @Override
+    NativeEventQueue getNativeEventQueue() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    public PrintJob getPrintJob(Frame frame, String jobtitle, JobAttributes jobAttributes, 
+            PageAttributes pageAttributes) throws IllegalArgumentException {
+        throw new IllegalArgumentException();        
+    }
+    
+    @Override
+    public PrintJob getPrintJob(Frame frame, String jobtitle, Properties props) throws NullPointerException  {
+        throw new NullPointerException();
+    }
+    */
+
+    @Override
+    public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public int getScreenResolution() throws HeadlessException {
+        throw new HeadlessException();
+    }    
+
+    @Override
+    public Dimension getScreenSize() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    //???AWT
+    /*
+    @Override
+    public Clipboard getSystemClipboard() throws HeadlessException {
+        throw new HeadlessException();
+    }    
+    
+    @Override
+    public Clipboard getSystemSelection() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    
+    @Override
+    WindowFactory getWindowFactory() throws HeadlessException {
+        throw new HeadlessException();
+    }
+    */
+
+    @Override
+    protected void init() {
+        lockAWT();
+        try {
+            ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
+            //???AWT: new EventQueue(this); // create the system EventQueue
+            //???AWT: dispatcher = new Dispatcher(this);
+            desktopProperties = new HashMap<String, Object>();
+            //???AWT: desktopPropsSupport = new PropertyChangeSupport(this);
+//          ???AWT: awtEventsManager = new AWTEventsManager();
+//          ???AWT: dispatchThread = new HeadlessEventDispatchThread(this, dispatcher);            
+//          ???AWT: dtk = DTK.getDTK();
+            dispatchThread.start();            
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public boolean isDynamicLayoutActive() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected boolean isDynamicLayoutSet() throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public boolean isFrameStateSupported(int state) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    protected void loadSystemColors(int[] systemColors) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(
+            InputMethodHighlight highlight) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public void setDynamicLayout(boolean dynamic) throws HeadlessException {
+        throw new HeadlessException();
+    }
+
+    @Override
+    public void setLockingKeyState(int keyCode, boolean on) throws UnsupportedOperationException {
+        throw new HeadlessException();
+    }
+}
diff --git a/awt/java/awt/IllegalComponentStateException.java b/awt/java/awt/IllegalComponentStateException.java
new file mode 100644
index 0000000..21dc35f
--- /dev/null
+++ b/awt/java/awt/IllegalComponentStateException.java
@@ -0,0 +1,51 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The IllegalComponentStateException class is used to provide 
+ * notification that AWT component is not in an appropriate state 
+ * for the requested operation.
+ */
+public class IllegalComponentStateException extends IllegalStateException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1889339587208144238L;
+
+    /**
+     * Instantiates a new IllegalComponentStateException with
+     * the specified message.
+     * 
+     * @param s the String message which describes the exception.
+     */
+    public IllegalComponentStateException(String s) {
+        super(s);
+    }
+
+    /**
+     * Instantiates a new IllegalComponentStateException without
+     * detailed message.
+     */
+    public IllegalComponentStateException() {
+    }
+
+}
+
diff --git a/awt/java/awt/Image.java b/awt/java/awt/Image.java
new file mode 100644
index 0000000..c217e38
--- /dev/null
+++ b/awt/java/awt/Image.java
@@ -0,0 +1,203 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.AreaAveragingScaleFilter;
+import java.awt.image.FilteredImageSource;
+import java.awt.image.ImageFilter;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.ReplicateScaleFilter;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Image abstract class represents the graphic images. 
+ */
+public abstract class Image {
+
+    /** 
+     * The UndefinedProperty object should be returned if
+     * property is not defined for a particular image. 
+     */
+    public static final Object UndefinedProperty = new Object();  //$NON-LOCK-1$
+
+    /** 
+     * The Constant SCALE_DEFAULT indicates the default image
+     * scaling algorithm. 
+     */
+    public static final int SCALE_DEFAULT = 1;
+
+    /** 
+     * The Constant SCALE_FAST indicates an image scaling algorithm which 
+     * places a higher priority on scaling speed than on the image's smoothness. 
+     */
+    public static final int SCALE_FAST = 2;
+
+    /** 
+     * The Constant SCALE_SMOOTH indicates an image scaling algorithm which 
+     * places a higher priority on image smoothness than on scaling speed. 
+     */
+    public static final int SCALE_SMOOTH = 4;
+
+    /** 
+     * The Constant SCALE_REPLICATE indicates the image scaling 
+     * algorithm in the ReplicateScaleFilter class. 
+     */
+    public static final int SCALE_REPLICATE = 8;
+
+    /** 
+     * The Constant SCALE_AREA_AVERAGING indicates  
+     * the area averaging image scaling algorithm. 
+     */
+    public static final int SCALE_AREA_AVERAGING = 16;
+
+    /** 
+     * The acceleration priority indicates image acceleration.   
+     */
+    protected float accelerationPriority = 0.5f;
+
+    /** The Constant capabilities. */
+    private static final ImageCapabilities capabilities = new ImageCapabilities(false);
+
+    /**
+     * Gets the image property with the specified name.
+     * The UndefinedProperty object should be return if the property is 
+     * not specified for this image.  The return value should be null if the
+     * property is currently unknown yet and the specified ImageObserver is
+     * to be notified later. 
+     * 
+     * @param name the name of image's property.
+     * @param observer the ImageObserver.
+     * 
+     * @return the Object which represents value of the specified property.
+     */
+    public abstract Object getProperty(String name, ImageObserver observer);
+
+    /**
+     * Gets the ImageProducer object which represents data of this Image.
+     * 
+     * @return the ImageProducer object which represents data of this Image.
+     */
+    public abstract ImageProducer getSource();
+
+    /**
+     * Gets the width of this image. The specified ImageObserver object 
+     * is notified when the width of this image is available.
+     * 
+     * @param observer the ImageObserver object which is 
+     * is notified when the width of this image is available.
+     * 
+     * @return the width of image, or -1 if the width of this image 
+     * is not available.
+     */
+    public abstract int getWidth(ImageObserver observer);
+
+    /**
+     * Gets the height of this image. The specified ImageObserver object 
+     * is notified when the height of this image is available.
+     * 
+     * @param observer the ImageObserver object which is 
+     * is notified when the height of this image is available.
+     * 
+     * @return the height of image, or -1 if the height of this image 
+     * is not available.
+     */
+    public abstract int getHeight(ImageObserver observer);
+
+    /**
+     * Gets the scaled instance of this Image. This method returns 
+     * an Image object constructed from the source of this image 
+     * with the specified width, height, and applied scaling
+     * alghorithm.
+     * 
+     * @param width the width of scaled Image. 
+     * @param height the height of scaled Image.
+     * @param hints the constant which indicates scaling algorithm. 
+     * 
+     * @return the scaled Image.
+     */
+    public Image getScaledInstance(int width, int height, int hints) {
+        ImageFilter filter;
+        if ((hints & (SCALE_SMOOTH | SCALE_AREA_AVERAGING)) != 0) {
+            filter = new AreaAveragingScaleFilter(width, height);
+        } else {
+            filter = new ReplicateScaleFilter(width, height);
+        }
+        ImageProducer producer = new FilteredImageSource(getSource(), filter);
+        return Toolkit.getDefaultToolkit().createImage(producer);
+    }
+
+    /**
+     * Gets a Graphics object for rendering this image. 
+     * This method can be used for off-screen images.
+     * 
+     * @return a Graphics object for rendering to this image.
+     */
+    public abstract Graphics getGraphics();
+
+    /**
+     * Flushes resources which are used by this Image object. 
+     * This method resets the image to the reconstructered state
+     * from the image's source.
+     */
+    public abstract void flush();
+
+    /**
+     * Gets the acceleration priority of this image.
+     * 
+     * @return the acceleration priority of this image.
+     */
+    public float getAccelerationPriority() {
+        return accelerationPriority;
+    }
+
+    /**
+     * Sets the acceleration priority for this image.  
+     *  
+     * @param priority the new acceleration priority (value in the
+     * range 0-1).
+     */
+    public void setAccelerationPriority(float priority) {
+        if (priority < 0 || priority > 1) {
+            // awt.10A=Priority must be a value between 0 and 1, inclusive
+            throw new IllegalArgumentException(Messages.getString("awt.10A")); //$NON-NLS-1$
+        }
+        accelerationPriority = priority;
+    }
+
+    /**
+     * Gets an ImageCapabilities object of this Image object
+     * for the specified GraphicsConfiguration. 
+     * 
+     * @param gc the specified GraphicsConfiguration object 
+     * (null value means default GraphicsConfiguration).
+     * 
+     * @return an ImageCapabilities object of this Image object
+     * for the specified GraphicsConfiguration.
+     */
+    public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
+        // Note: common image is not accelerated.
+        return capabilities;
+    }
+}
+
+
diff --git a/awt/java/awt/ImageCapabilities.java b/awt/java/awt/ImageCapabilities.java
new file mode 100644
index 0000000..6e9ecfc
--- /dev/null
+++ b/awt/java/awt/ImageCapabilities.java
@@ -0,0 +1,74 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The ImageCapabilities class gives information about an image's capabilities.
+ */
+public class ImageCapabilities implements Cloneable {
+    
+    /** The accelerated. */
+    private final boolean accelerated;
+
+    /**
+     * Instantiates a new ImageCapabilities with the specified
+     * acceleration flag which indicates whether acceleration
+     * is desired or not.
+     * 
+     * @param accelerated the accelerated flag.
+     */
+    public ImageCapabilities(boolean accelerated) {
+        this.accelerated = accelerated;
+    }
+
+    /**
+     * Returns a copy of this ImageCapabilities object.
+     * 
+     * @return the copy of this ImageCapabilities object.
+     */
+    @Override
+    public Object clone() {
+        return new ImageCapabilities(accelerated);
+    }
+
+    /**
+     * Returne true if the Image of this ImageCapabilities is or can be
+     * accelerated.
+     *  
+     * @return true, if the Image of this ImageCapabilities is or can be
+     * accelerated, false otherwise.
+     */
+    public boolean isAccelerated() {
+        return accelerated;
+    }
+
+    /**
+     * Returns true if this ImageCapabilities applies to
+     * the VolatileImage which can lose its surfaces.
+     * 
+     * @return true if this ImageCapabilities applies to
+     * the VolatileImage which can lose its surfaces, 
+     * false otherwise.
+     */
+    public boolean isTrueVolatile() {
+        return true;
+    }
+}
diff --git a/awt/java/awt/Insets.java b/awt/java/awt/Insets.java
new file mode 100644
index 0000000..61f3fd8
--- /dev/null
+++ b/awt/java/awt/Insets.java
@@ -0,0 +1,165 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.io.Serializable;
+
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The Insets class represents the borders of a container. 
+ * This class describes the space that a container should leave at each edge:
+ * the top, the bottom, the right side, and the left side. 
+ * The space can be filled with a border, a blank space, or a title.
+ */
+public class Insets implements Cloneable, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -2272572637695466749L;
+
+    /**
+     * The top inset indicates the size of the space added to the 
+     * top of the rectangle.
+     */
+    public int top;
+
+    /** 
+     * The left inset indicates the size of the space added to the 
+     * left side of the rectangle.
+     */
+    public int left;
+
+    /** 
+     * The bottom inset indicates the size of the space subtracted from 
+     * the bottom of the rectangle.
+     */
+    public int bottom;
+
+    /** The right inset indicates the size of the space subtracted from 
+     * the right side of the rectangle. 
+     */
+    public int right;
+
+    /**
+     * Instantiates a new Inset object with the specified top, left, bottom,
+     * right parameters.
+     * 
+     * @param top the top inset.
+     * @param left the left inset.
+     * @param bottom the bottom inset.
+     * @param right the right inset.
+     */
+    public Insets(int top, int left, int bottom, int right) {
+        setValues(top, left, bottom, right);
+    }
+
+    /**
+     * Returns a hash code of the Insets object.
+     * 
+     * @return a hash code of the Insets object.
+     */
+    @Override
+    public int hashCode() {
+        int hashCode = HashCode.EMPTY_HASH_CODE;
+        hashCode = HashCode.combine(hashCode, top);
+        hashCode = HashCode.combine(hashCode, left);
+        hashCode = HashCode.combine(hashCode, bottom);
+        hashCode = HashCode.combine(hashCode, right);
+        return hashCode;
+    }
+
+    /**
+     * Returns a copy of this Insets object.
+     * 
+     * @return a copy of this Insets object.
+     */
+    @Override
+    public Object clone() {
+        return new Insets(top, left, bottom, right);
+    }
+
+    /**
+     * Checks if this Insets object is equal to the specified object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if the object is an Insets object whose data values
+     * are equal to those of this object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof Insets) {
+            Insets i = (Insets) o;
+            return ((i.left == left) && (i.bottom == bottom) &&
+                    (i.right == right) && (i.top == top));
+        }
+        return false;
+    }
+
+    /**
+     * Returns a String representation of this Insets object.
+     * 
+     * @return a String representation of this Insets object.
+     */
+    @Override
+    public String toString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * System.out.println(new Insets(1, 2, 3, 4));
+         */
+
+        return (getClass().getName() +
+                "[left=" + left + ",top=" + top + //$NON-NLS-1$ //$NON-NLS-2$
+                ",right=" + right + ",bottom="  + bottom + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Sets top, left, bottom, and right insets to the specified values.
+     * 
+     * @param top the top inset.
+     * @param left the left inset.
+     * @param bottom the bottom inset.
+     * @param right the right inset.
+     */
+    public void set(int top, int left, int bottom, int right) {
+        setValues(top, left, bottom, right);
+    }
+
+    /**
+     * Sets the values.
+     * 
+     * @param top the top
+     * @param left the left
+     * @param bottom the bottom
+     * @param right the right
+     */
+    private void setValues(int top, int left, int bottom, int right) {
+        this.top = top;
+        this.left = left;
+        this.bottom = bottom;
+        this.right = right;
+    }
+}
+
diff --git a/awt/java/awt/ItemSelectable.java b/awt/java/awt/ItemSelectable.java
new file mode 100644
index 0000000..a46364b
--- /dev/null
+++ b/awt/java/awt/ItemSelectable.java
@@ -0,0 +1,53 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.ItemListener;
+
+/**
+ * The ItemSelectable interface represents a set of items which can be selected.
+ */
+public interface ItemSelectable {
+
+    /**
+     * Adds an ItemListener for receiving item events when the state of an item 
+     * is changed by the user. 
+     * 
+     * @param l the ItemListener.
+     */
+    public void addItemListener(ItemListener l);
+
+    /**
+     * Gets an array of the selected objects or null if there is no selected object.
+     * 
+     * @return an array of the selected objects or null if there is no selected 
+     * object.
+     */
+    public Object[] getSelectedObjects();
+
+    /**
+     * Removes the specified ItemListener.
+     * 
+     * @param l the ItemListener which will be removed.
+     */
+    public void removeItemListener(ItemListener l);
+
+}
diff --git a/awt/java/awt/MenuComponent.java b/awt/java/awt/MenuComponent.java
new file mode 100644
index 0000000..9eb4f3d
--- /dev/null
+++ b/awt/java/awt/MenuComponent.java
@@ -0,0 +1,1041 @@
+/*
+ *  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 java.awt;
+
+import java.awt.event.FocusListener;
+import java.awt.event.MouseEvent;
+import java.awt.peer.MenuComponentPeer;
+import java.io.Serializable;
+import java.util.Locale;
+//import javax.accessibility.Accessible;
+//import javax.accessibility.AccessibleComponent;
+//import javax.accessibility.AccessibleContext;
+//import javax.accessibility.AccessibleRole;
+//import javax.accessibility.AccessibleSelection;
+//import javax.accessibility.AccessibleStateSet;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.state.MenuItemState;
+import org.apache.harmony.awt.state.MenuState;
+
+/**
+ * The MenuComponent abstract class is the superclass for menu 
+ * components. Menu components receive and process AWT events.
+ */
+public abstract class MenuComponent implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4536902356223894379L;
+
+    /** The name. */
+    private String name;
+
+    /** The font. */
+    private Font font;
+
+    /** The parent. */
+    MenuContainer parent;
+
+    /** The deprecated event handler. */
+    boolean deprecatedEventHandler = true;
+
+    /** The selected item index. */
+    private int selectedItemIndex;
+
+    //???AWT: private AccessibleContext accessibleContext;
+
+    /** The toolkit. */
+    final Toolkit toolkit = Toolkit.getDefaultToolkit();
+
+    //???AWT
+    /*
+    protected abstract class AccessibleAWTMenuComponent extends AccessibleContext implements
+            Serializable, AccessibleComponent, AccessibleSelection {
+        private static final long serialVersionUID = -4269533416223798698L;
+
+        public void addFocusListener(FocusListener listener) {
+        }
+
+        public boolean contains(Point pt) {
+            return false;
+        }
+
+        public Accessible getAccessibleAt(Point pt) {
+            return null;
+        }
+
+        public Color getBackground() {
+            return null;
+        }
+
+        public Rectangle getBounds() {
+            return null;
+        }
+
+        public Cursor getCursor() {
+            return null;
+        }
+
+        public Font getFont() {
+            return MenuComponent.this.getFont();
+        }
+
+        public FontMetrics getFontMetrics(Font font) {
+            return null;
+        }
+
+        public Color getForeground() {
+            return null;
+        }
+
+        public Point getLocation() {
+            return null;
+        }
+
+        public Point getLocationOnScreen() {
+            return null;
+        }
+
+        public Dimension getSize() {
+            return null;
+        }
+
+        public boolean isEnabled() {
+            return true; // always enabled
+        }
+
+        public boolean isFocusTraversable() {
+            return true; // always focus traversable
+        }
+
+        public boolean isShowing() {
+            return true;// always showing
+        }
+
+        public boolean isVisible() {
+            return true; // always visible
+        }
+
+        public void removeFocusListener(FocusListener listener) {
+        }
+
+        public void requestFocus() {
+        }
+
+        public void setBackground(Color color) {
+        }
+
+        public void setBounds(Rectangle rect) {
+        }
+
+        public void setCursor(Cursor cursor) {
+        }
+
+        public void setEnabled(boolean enabled) {
+        }
+
+        public void setFont(Font font) {
+            MenuComponent.this.setFont(font);
+        }
+
+        public void setForeground(Color color) {
+        }
+
+        public void setLocation(Point pt) {
+        }
+
+        public void setSize(Dimension pt) {
+        }
+
+        public void setVisible(boolean visible) {
+        }
+
+        public void addAccessibleSelection(int index) {
+        }
+
+        public void clearAccessibleSelection() {
+        }
+
+        public Accessible getAccessibleSelection(int index) {
+            return null;
+        }
+
+        public int getAccessibleSelectionCount() {
+            return 0;
+        }
+
+        public boolean isAccessibleChildSelected(int index) {
+            return false;
+        }
+
+        public void removeAccessibleSelection(int index) {
+        }
+
+        public void selectAllAccessibleSelection() {
+        }
+
+        @Override
+        public Accessible getAccessibleChild(int index) {
+            return null;
+        }
+
+        @Override
+        public int getAccessibleChildrenCount() {
+            return 0;
+        }
+
+        @Override
+        public AccessibleComponent getAccessibleComponent() {
+            return this;
+        }
+
+        @Override
+        public String getAccessibleDescription() {
+            return super.getAccessibleDescription();
+        }
+
+        @Override
+        public int getAccessibleIndexInParent() {
+            toolkit.lockAWT();
+            try {
+                Accessible aParent = getAccessibleParent();
+                int aIndex = -1;
+                if (aParent instanceof MenuComponent) {
+                    MenuComponent parent = (MenuComponent) aParent;
+                    int count = parent.getItemCount();
+                    for (int i = 0; i < count; i++) {
+                        MenuComponent comp = parent.getItem(i);
+                        if (comp instanceof Accessible) {
+                            aIndex++;
+                            if (comp == MenuComponent.this) {
+                                return aIndex;
+                            }
+                        }
+                    }
+                }
+                return -1;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public String getAccessibleName() {
+            return super.getAccessibleName();
+        }
+
+        @Override
+        public Accessible getAccessibleParent() {
+            toolkit.lockAWT();
+            try {
+                Accessible aParent = super.getAccessibleParent();
+                if (aParent != null) {
+                    return aParent;
+                }
+                MenuContainer parent = getParent();
+                if (parent instanceof Accessible) {
+                    aParent = (Accessible) parent;
+                }
+                return aParent;
+            } finally {
+                toolkit.unlockAWT();
+            }
+        }
+
+        @Override
+        public AccessibleRole getAccessibleRole() {
+            return AccessibleRole.AWT_COMPONENT;
+        }
+
+        @Override
+        public AccessibleSelection getAccessibleSelection() {
+            return this;
+        }
+
+        @Override
+        public AccessibleStateSet getAccessibleStateSet() {
+            return new AccessibleStateSet();
+        }
+
+        @Override
+        public Locale getLocale() {
+            return Locale.getDefault();
+        }
+    }
+    */
+
+    /**
+     * The accessor to MenuComponent internal state,
+     * utilized by the visual theme.
+     * 
+     * @throws HeadlessException the headless exception
+     */
+    //???AWT
+    /*
+    class State implements MenuState {
+        Dimension size;
+
+        Dimension getSize() {
+            if (size == null) {
+                calculate();
+            }
+            return size;
+        }
+
+        public int getWidth() {
+            return getSize().width;
+        }
+
+        public int getHeight() {
+            return getSize().height;
+        }
+
+        public Font getFont() {
+            return MenuComponent.this.getFont();
+        }
+
+        public int getItemCount() {
+            return MenuComponent.this.getItemCount();
+        }
+
+        public int getSelectedItemIndex() {
+            return MenuComponent.this.getSelectedItemIndex();
+        }
+
+        public boolean isFontSet() {
+            return MenuComponent.this.isFontSet();
+        }
+
+        @SuppressWarnings("deprecation")
+        public FontMetrics getFontMetrics(Font f) {
+            return MenuComponent.this.toolkit.getFontMetrics(f);
+        }
+
+        public Point getLocation() {
+            return MenuComponent.this.getLocation();
+        }
+
+        public MenuItemState getItem(int index) {
+            MenuItem item = MenuComponent.this.getItem(index);
+            return item.itemState;
+        }
+
+        public void setSize(int w, int h) {
+            this.size = new Dimension(w, h);
+        }
+
+        void calculate() {
+            size = new Dimension();
+            size.setSize(toolkit.theme.calculateMenuSize(this));
+        }
+
+        void reset() {
+            for (int i = 0; i < getItemCount(); i++) {
+                ((MenuItem.State) getItem(i)).reset();
+            }
+        }
+
+    }
+    */
+    
+    /**
+     * Pop-up box for menu. It transfers the paint events, 
+     * keyboard and mouse events to the menu component itself
+     */
+    //???AWT
+    /*
+    class MenuPopupBox extends PopupBox {
+        private final Point lastMousePos = new Point();
+
+        @Override
+        boolean isMenu() {
+            return true;
+        }
+
+        @Override
+        void paint(Graphics gr) {
+            MenuComponent.this.paint(gr);
+        }
+
+        @Override
+        void onKeyEvent(int eventId, int vKey, long when, int modifiers) {
+            MenuComponent.this.onKeyEvent(eventId, vKey, when, modifiers);
+        }
+
+        @Override
+        void onMouseEvent(int eventId, Point where, int mouseButton, long when, int modifiers,
+                int wheelRotation) {
+            // prevent conflict of mouse and keyboard
+            // when sub-menu drops down due to keyboard navigation
+            if (lastMousePos.equals(where)
+                    && (eventId == MouseEvent.MOUSE_MOVED || eventId == MouseEvent.MOUSE_ENTERED)) {
+                return;
+            }
+            lastMousePos.setLocation(where);
+            MenuComponent.this.onMouseEvent(eventId, where, mouseButton, when, modifiers);
+        }
+    }
+    */
+    
+    /**
+     * Instantiates a new MenuComponent object.
+     * 
+     * @throws HeadlessException if the graphical interface
+     * environment can't support MenuComponents
+     */
+    public MenuComponent() throws HeadlessException {
+        toolkit.lockAWT();
+        try {
+            Toolkit.checkHeadless();
+            name = autoName();
+            selectedItemIndex = -1;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the name of the MenuComponent object.
+     * 
+     * @return the name of the MenuComponent object.
+     */
+    public String getName() {
+        toolkit.lockAWT();
+        try {
+            return name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns a String representation of the MenuComponent object.
+     * 
+     * @return a String representation of the MenuComponent object.
+     */
+    @Override
+    public String toString() {
+        toolkit.lockAWT();
+        try {
+            return getClass().getName() + "[" + paramString() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the Parent menu Container .
+     * 
+     * @return the parent
+     */
+    public MenuContainer getParent() {
+        toolkit.lockAWT();
+        try {
+            return parent;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the name of the MenuComponent to the specified string.
+     * 
+     * @param name the new name of the MenuComponent object. 
+     */
+    public void setName(String name) {
+        toolkit.lockAWT();
+        try {
+            this.name = name;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Dispatches AWT event.
+     * 
+     * @param event the AWTEvent.
+     */
+    public final void dispatchEvent(AWTEvent event) {
+        toolkit.lockAWT();
+        try {
+            processEvent(event);
+            if (deprecatedEventHandler) {
+                postDeprecatedEvent(event);
+            }
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Post deprecated event.
+     * 
+     * @param event the event
+     */
+    void postDeprecatedEvent(AWTEvent event) {
+        Event evt = event.getEvent();
+        if (evt != null) {
+            postEvent(evt);
+        }
+    }
+
+    /**
+     * Gets the peer of the MenuComponent; an application must not
+     * use this method directly.
+     * 
+     * @return the MenuComponentPeer object.
+     *
+     * @deprecated an application must not use this method directly.
+     */
+    @Deprecated
+    public MenuComponentPeer getPeer() throws org.apache.harmony.luni.util.NotImplementedException {
+        toolkit.lockAWT();
+        try {
+        } finally {
+            toolkit.unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * Gets the locking object of this MenuComponent.
+     * 
+     * @return the locking object of this MenuComponent.
+     */
+    protected final Object getTreeLock() {
+        return toolkit.awtTreeLock;
+    }
+
+    /**
+     * Posts the Event to the MenuComponent.
+     * 
+     * @param e the Event.
+     * 
+     * @return true, if the event is posted successfully; 
+     * false otherwise.
+     * 
+     * @deprecated Replaced dispatchEvent method.
+     */
+    @SuppressWarnings("deprecation")
+    @Deprecated
+    public boolean postEvent(Event e) {
+        toolkit.lockAWT();
+        try {
+            if (parent != null) {
+                return parent.postEvent(e);
+            }
+            return false;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the string representation of the MenuComponent state.
+     * 
+     * @return returns the string representation of the MenuComponent
+     * state.
+     */
+    protected String paramString() {
+        toolkit.lockAWT();
+        try {
+            return getName();
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    //???AWT
+    /*
+    public AccessibleContext getAccessibleContext() {
+        toolkit.lockAWT();
+        try {
+            if (accessibleContext == null) {
+                accessibleContext = createAccessibleContext();
+            }
+            return accessibleContext;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+    */
+
+    /**
+     * Gets the font of the MenuComponent object.
+     * 
+     * @return the Font of the MenuComponent object.
+     */
+    public Font getFont() {
+        toolkit.lockAWT();
+        try {
+            if (font == null && hasDefaultFont()) {
+                return toolkit.getDefaultFont();
+            }
+            if (font == null && parent != null) {
+                return parent.getFont();
+            }
+            return font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if is font set.
+     * 
+     * @return true, if is font set
+     */
+    boolean isFontSet() {
+        return font != null
+                || ((parent instanceof MenuComponent) && ((MenuComponent) parent).isFontSet());
+    }
+
+    /**
+     * Checks for default font.
+     * 
+     * @return true, if successful
+     */
+    boolean hasDefaultFont() {
+        return false;
+    }
+
+    /**
+     * Processes an AWTEevent on this menu component.
+     * 
+     * @param event the AWTEvent.
+     */
+    protected void processEvent(AWTEvent event) {
+        toolkit.lockAWT();
+        try {
+            // do nothing
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Removes the peer of the MenuComponent.
+     */
+    public void removeNotify() {
+        toolkit.lockAWT();
+        try {
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the Font for this MenuComponent object.
+     * 
+     * @param font the new Font to be used for this MenuComponent.
+     */
+    public void setFont(Font font) {
+        toolkit.lockAWT();
+        try {
+            this.font = font;
+        } finally {
+            toolkit.unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the parent.
+     * 
+     * @param parent the new parent
+     */
+    void setParent(MenuContainer parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Gets the location.
+     * 
+     * @return the location
+     */
+    Point getLocation() {
+        // to be overridden
+        return new Point(0, 0);
+    }
+
+    /**
+     * Gets the width.
+     * 
+     * @return the width
+     */
+    int getWidth() {
+        // to be overridden
+        return 1;
+    }
+
+    /**
+     * Gets the height.
+     * 
+     * @return the height
+     */
+    int getHeight() {
+        // to be overridden
+        return 1;
+    }
+
+    /**
+     * Recursively find the menu item for a menu shortcut.
+     * 
+     * @param gr the gr
+     * 
+     * @return the menu item;
+     * or null if the item is not available for this shortcut
+     */
+    //???AWT
+    /*
+    MenuItem getShortcutMenuItemImpl(MenuShortcut ms) {
+        if (ms == null) {
+            return null;
+        }
+        for (int i = 0; i < getItemCount(); i++) {
+            MenuItem mi = getItem(i);
+            if (mi instanceof Menu) {
+                mi = ((Menu) mi).getShortcutMenuItemImpl(ms);
+                if (mi != null) {
+                    return mi;
+                }
+            } else if (ms.equals(mi.getShortcut())) {
+                return mi;
+            }
+        }
+        return null;
+    }
+    */
+
+    void paint(Graphics gr) {
+        gr.setColor(Color.LIGHT_GRAY);
+        gr.fillRect(0, 0, getWidth(), getHeight());
+        gr.setColor(Color.BLACK);
+    }
+
+    /**
+     * Mouse events handler.
+     * 
+     * @param eventId - one of the MouseEvent.MOUSE_* constants
+     * @param where - mouse location
+     * @param mouseButton - mouse button that was pressed or released
+     * @param when - event time
+     * @param modifiers - input event modifiers
+     */
+    void onMouseEvent(int eventId, Point where, int mouseButton, long when, int modifiers) {
+        // to be overridden
+    }
+
+    /**
+     * Keyboard event handler.
+     * 
+     * @param eventId - one of the KeyEvent.KEY_* constants
+     * @param vKey - the key code
+     * @param when - event time
+     * @param modifiers - input event modifiers
+     */
+    void onKeyEvent(int eventId, int vKey, long when, int modifiers) {
+        // to be overridden
+    }
+
+    /**
+     * Post the ActionEvent or ItemEvent,
+     * depending on type of the menu item.
+     * 
+     * @param index the index
+     * 
+     * @return the item rect
+     */
+    //???AWT
+    /*
+    void fireItemAction(int item, long when, int modifiers) {
+        MenuItem mi = getItem(item);
+        mi.itemSelected(when, modifiers);
+    }
+
+    MenuItem getItem(int index) {
+        // to be overridden
+        return null;
+    }
+
+    int getItemCount() {
+        return 0;
+    }
+    */
+
+    /**
+     * @return The sub-menu of currently selecetd item, 
+     * or null if such a sub-menu is not available 
+     */
+    //???AWT
+    /*
+    Menu getSelectedSubmenu() {
+        if (selectedItemIndex < 0) {
+            return null;
+        }
+        MenuItem item = getItem(selectedItemIndex);
+        return (item instanceof Menu) ? (Menu) item : null;
+    }
+    */
+
+    /**
+     * Convenience method for selectItem(index, true)
+     */
+    //???AWT
+    /*
+    void selectItem(int index) {
+        selectItem(index, true);
+    }
+    */
+
+    /**
+     * Change the selection in the menu 
+     * @param index - new selecetd item's index
+     * @param showSubMenu - if new selected item has a sub-menu,
+     * should that sub-menu be displayed 
+     */
+    //???AWT
+    /*
+    void selectItem(int index, boolean showSubMenu) {
+        if (selectedItemIndex == index) {
+            return;
+        }
+        if (selectedItemIndex >= 0 && getItem(selectedItemIndex) instanceof Menu) {
+            ((Menu) getItem(selectedItemIndex)).hide();
+        }
+        MultiRectArea clip = getUpdateClip(index, selectedItemIndex);
+        selectedItemIndex = index;
+        Graphics gr = getGraphics(clip);
+        if (gr != null) {
+            paint(gr);
+        }
+        if (showSubMenu) {
+            showSubMenu(selectedItemIndex);
+        }
+    }
+    */
+
+    /**
+     * Change the selected item to the next one in the requested direction
+     * moving cyclically, skipping separators
+     * @param forward - the direction to move the selection
+     * @param showSubMenu - if new selected item has a sub-menu,
+     * should that sub-menu be displayed 
+     */
+    //???AWT
+    /*
+    void selectNextItem(boolean forward, boolean showSubMenu) {
+        int selected = getSelectedItemIndex();
+        int count = getItemCount();
+        if (count == 0) {
+            return;
+        }
+        if (selected < 0) {
+            selected = (forward ? count - 1 : 0);
+        }
+        int i = selected;
+        do {
+            i = (forward ? (i + 1) : (i + count - 1)) % count;
+            i %= count;
+            MenuItem item = getItem(i);
+            if (!"-".equals(item.getLabel())) { //$NON-NLS-1$
+                selectItem(i, showSubMenu);
+                return;
+            }
+        } while (i != selected);
+    }
+
+    
+    void showSubMenu(int index) {
+        if ((index < 0) || !isActive()) {
+            return;
+        }
+        MenuItem item = getItem(index);
+        if (item instanceof Menu) {
+            Menu menu = ((Menu) getItem(index));
+            if (menu.getItemCount() == 0) {
+                return;
+            }
+            Point location = getSubmenuLocation(index);
+            menu.show(location.x, location.y, false);
+        }
+    }
+    */
+
+    /**
+     * @return - the menu bar which is the root of crrent menu's hierarchy;
+     * or null if the hierarchy root is not a menu bar 
+     */
+    //???AWT
+    /*
+    MenuBar getMenuBar() {
+        if (parent instanceof MenuBar) {
+            return (MenuBar) parent;
+        }
+        if (parent instanceof MenuComponent) {
+            return ((MenuComponent) parent).getMenuBar();
+        }
+        return null;
+    }
+
+    PopupBox getPopupBox() {
+        return null;
+    }
+    */
+
+    Rectangle getItemRect(int index) {
+        // to be overridden
+        return null;
+    }
+
+    /**
+     * Determine the clip region when menu selection is changed
+     * from index1 to index2.
+     * 
+     * @param index1 - old selected intem
+     * @param index2 - new selected item
+     * 
+     * @return - the region to repaint
+     */
+    final MultiRectArea getUpdateClip(int index1, int index2) {
+        MultiRectArea clip = new MultiRectArea();
+        if (index1 >= 0) {
+            clip.add(getItemRect(index1));
+        }
+        if (index2 >= 0) {
+            clip.add(getItemRect(index2));
+        }
+        return clip;
+    }
+
+    /**
+     * Gets the submenu location.
+     * 
+     * @param index the index
+     * 
+     * @return the submenu location
+     */
+    Point getSubmenuLocation(int index) {
+        // to be overridden
+        return new Point(0, 0);
+    }
+
+    /**
+     * Gets the selected item index.
+     * 
+     * @return the selected item index
+     */
+    int getSelectedItemIndex() {
+        return selectedItemIndex;
+    }
+
+    /**
+     * Hide.
+     */
+    void hide() {
+        selectedItemIndex = -1;
+        if (parent instanceof MenuComponent) {
+            ((MenuComponent) parent).itemHidden(this);
+        }
+    }
+
+    /**
+     * Item hidden.
+     * 
+     * @param mc the mc
+     */
+    void itemHidden(MenuComponent mc) {
+        // to be overridden
+    }
+
+    /**
+     * Checks if is visible.
+     * 
+     * @return true, if is visible
+     */
+    boolean isVisible() {
+        return true;
+    }
+
+    /**
+     * Checks if is active.
+     * 
+     * @return true, if is active
+     */
+    boolean isActive() {
+        return true;
+    }
+
+    /**
+     * Hide all menu hierarchy.
+     */
+    void endMenu() {
+        //???AWT: toolkit.dispatcher.popupDispatcher.deactivateAll();
+    }
+
+    /**
+     * Handle the mouse click or Enter key event on a menu's item.
+     * 
+     * @param when - the event time
+     * @param modifiers - input event modifiers
+     */
+    void itemSelected(long when, int modifiers) {
+        endMenu();
+    }
+
+    /**
+     * Auto name.
+     * 
+     * @return the string
+     */
+    String autoName() {
+        String name = getClass().getName();
+        if (name.indexOf("$") != -1) { //$NON-NLS-1$
+            return null;
+        }
+        //???AWT: int number = toolkit.autoNumber.nextMenuComponent++;
+        int number = 0;
+        name = name.substring(name.lastIndexOf(".") + 1) + Integer.toString(number); //$NON-NLS-1$
+        return name;
+    }
+
+    /**
+     * Creates the Graphics object for the pop-up box of this menu component.
+     * 
+     * @param clip - the clip to set on this Graphics
+     * 
+     * @return - the created Graphics object,
+     * or null if such object is not available.
+     */
+    Graphics getGraphics(MultiRectArea clip) {
+        // to be overridden
+        return null;
+    }
+
+    /**
+     * @return accessible context specific for particular menu component
+     */
+    //???AWT
+    /*
+    AccessibleContext createAccessibleContext() {
+        return null;
+    }
+    */
+}
diff --git a/awt/java/awt/MenuContainer.java b/awt/java/awt/MenuContainer.java
new file mode 100644
index 0000000..7a48f13
--- /dev/null
+++ b/awt/java/awt/MenuContainer.java
@@ -0,0 +1,56 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The MenuContainer interface represents all menu containers.
+ */
+public interface MenuContainer {
+
+    /**
+     * Removes the specified MenuComponent from the MenuContainer.
+     * 
+     * @param c the MenuComponent.
+     */
+    public void remove(MenuComponent c);
+
+    /**
+     * Gets the Font of the MenuContainer.
+     * 
+     * @return the font of the MenuContainer.
+     */
+    public Font getFont();
+
+    /**
+     * Posts an Event.
+     * 
+     * @param e the Event.
+     * 
+     * @return true if the event is posted successfully; 
+     * false otherwise.
+     * 
+     * @deprecated Replaced by dispatchEvent method.
+     */
+    @Deprecated
+    public boolean postEvent(Event e);
+
+}
+
diff --git a/awt/java/awt/ModalContext.java b/awt/java/awt/ModalContext.java
new file mode 100644
index 0000000..32a5912
--- /dev/null
+++ b/awt/java/awt/ModalContext.java
@@ -0,0 +1,64 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ *
+ * The context for nested event loop. It can be dialog, popup menu etc.
+ */
+class ModalContext {
+
+    private boolean running = false;
+
+    private final Toolkit toolkit;
+
+    ModalContext() {
+        toolkit = Toolkit.getDefaultToolkit();
+    }
+
+    /**
+     * Set up and run modal loop in this context
+     *
+     */
+    void runModalLoop() {
+        running = true;
+        toolkit.dispatchThread.runModalLoop(this);
+    }
+
+    /**
+     * Leave the modal loop running in this context
+     * This method doesn't stops the loop immediately,
+     * it just sets the flag that says the modal loop to stop
+     *
+     */
+    void endModalLoop() {
+        running = false;
+    }
+
+    /**
+     *
+     * @return modal loop is currently running in this context
+     */
+    boolean isModalLoopRunning() {
+        return running;
+    }
+
+}
diff --git a/awt/java/awt/MouseDispatcher.java b/awt/java/awt/MouseDispatcher.java
new file mode 100644
index 0000000..df48f9d
--- /dev/null
+++ b/awt/java/awt/MouseDispatcher.java
@@ -0,0 +1,418 @@
+/*
+ *  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 Dmitry A. Durnev, Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.Dispatcher.MouseGrabManager;
+import java.util.EventListener;
+
+import org.apache.harmony.awt.wtk.NativeEvent;
+import org.apache.harmony.awt.wtk.NativeWindow;
+
+
+class MouseDispatcher {
+
+    // Fields for synthetic mouse click events generation
+    private static final int clickDelta = 5;
+    private final long[] lastPressTime = new long[] {0l, 0l, 0l};
+    private final Point[] lastPressPos = new Point[] {null, null, null};
+    private final boolean[] buttonPressed = new boolean[] {false, false, false};
+    private final int[] clickCount = new int[] {0, 0, 0};
+
+    // Fields for mouse entered/exited support
+    private Component lastUnderPointer = null;
+    private final Point lastScreenPos = new Point(-1, -1);
+
+    // Fields for redundant mouse moved/dragged filtering
+    private Component lastUnderMotion = null;
+    private Point lastLocalPos = new Point(-1, -1);
+
+    private final MouseGrabManager mouseGrabManager;
+    private final Toolkit toolkit;
+
+    static Point convertPoint(Component src, int x, int y, Component dest) {
+        Point srcPoint = getAbsLocation(src);
+        Point destPoint = getAbsLocation(dest);
+
+        return new Point(x + (srcPoint.x - destPoint.x),
+                         y + (srcPoint.y - destPoint.y));
+    }
+
+    static Point convertPoint(Component src, Point p, Component dst) {
+        return convertPoint(src, p.x, p.y, dst);
+    }
+
+    private static Point getAbsLocation(Component comp) {
+        Point location = new Point(0, 0);
+// BEGIN android-changed: AWT components not supported
+//        for (Component parent = comp; parent != null; parent = parent.parent) {
+//            Point parentPos = (parent instanceof EmbeddedWindow ?
+//                               parent.getNativeWindow().getScreenPos() :
+//                               parent.getLocation());
+//
+//            location.translate(parentPos.x, parentPos.y);
+//
+//            if (parent instanceof Window) {
+//                break;
+//            }
+//        }
+// END android-changed
+
+        return location;
+    }
+
+    MouseDispatcher(MouseGrabManager mouseGrabManager,
+                    Toolkit toolkit) {
+        this.mouseGrabManager = mouseGrabManager;
+        this.toolkit = toolkit;
+    }
+
+    Point getPointerPos() {
+        return lastScreenPos;
+    }
+
+    boolean dispatch(Component src, NativeEvent event) {
+        int id = event.getEventId();
+
+        lastScreenPos.setLocation(event.getScreenPos());
+        checkMouseEnterExit(event.getInputModifiers(), event.getTime());
+
+        if (id == MouseEvent.MOUSE_WHEEL) {
+// BEGIN android-changed: AWT components not supported
+//            dispatchWheelEvent(src, event);
+// END android-changed
+        } else if ((id != MouseEvent.MOUSE_ENTERED) &&
+                   (id != MouseEvent.MOUSE_EXITED)) {
+            PointerInfo info = new PointerInfo(src, event.getLocalPos());
+
+            mouseGrabManager.preprocessEvent(event);
+            findEventSource(info);
+            if ((id == MouseEvent.MOUSE_PRESSED) ||
+                (id == MouseEvent.MOUSE_RELEASED)) {
+
+                dispatchButtonEvent(info, event);
+            } else if ((id == MouseEvent.MOUSE_MOVED) ||
+                       (id == MouseEvent.MOUSE_DRAGGED)) {
+
+                dispatchMotionEvent(info, event);
+            }
+        }
+
+        return false;
+    }
+
+    private void checkMouseEnterExit(int modifiers, long when) {
+// BEGIN android-changed: AWT components not supported
+//        PointerInfo info = findComponentUnderPointer();
+//        Component curUnderPointer =
+//                propagateEvent(info, AWTEvent.MOUSE_EVENT_MASK,
+//                               MouseListener.class, false).src;
+//
+//        if (curUnderPointer != lastUnderPointer) {
+//            Point pos = info.position;
+//            if ((lastUnderPointer != null) &&
+//                 lastUnderPointer.isMouseExitedExpected()) {
+//
+//                Point exitPos = convertPoint(null, lastScreenPos.x,
+//                                             lastScreenPos.y, lastUnderPointer);
+//
+//                postMouseEnterExit(MouseEvent.MOUSE_EXITED, modifiers, when,
+//                                   exitPos.x, exitPos.y, lastUnderPointer);
+//            }
+//            setCursor(curUnderPointer);
+//            if (curUnderPointer != null) {
+//                postMouseEnterExit(MouseEvent.MOUSE_ENTERED, modifiers, when,
+//                                   pos.x, pos.y, curUnderPointer);
+//            }
+//            lastUnderPointer = curUnderPointer;
+//        }
+// END android-changed
+    }
+
+    private void setCursor(Component comp) {
+        if (comp == null) {
+            return;
+        }
+        Component grabOwner = mouseGrabManager.getSyntheticGrabOwner();
+        Component cursorComp = ((grabOwner != null) &&
+                                 grabOwner.isShowing() ? grabOwner : comp);
+        cursorComp.setCursor();
+    }
+
+    private void postMouseEnterExit(int id, int mod, long when,
+                                    int x, int y, Component comp) {
+        if (comp.isIndirectlyEnabled()) {
+            toolkit.getSystemEventQueueImpl().postEvent(
+                    new MouseEvent(comp, id, when, mod, x, y, 0, false));
+            comp.setMouseExitedExpected(id == MouseEvent.MOUSE_ENTERED);
+        } else {
+            comp.setMouseExitedExpected(false);
+        }
+    }
+
+ // BEGIN android-changed: AWT components not supported
+//    private PointerInfo findComponentUnderPointer() {
+//        NativeWindow nativeWindow = toolkit.getWindowFactory().
+//        getWindowFromPoint(lastScreenPos);
+//
+//        if (nativeWindow != null) {
+//            Component comp = toolkit.getComponentById(nativeWindow.getId());
+//
+//            if (comp != null) {
+//                Window window = comp.getWindowAncestor();
+//                Point pointerPos = convertPoint(null, lastScreenPos.x,
+//                                                lastScreenPos.y, window);
+//
+//                if (window.getClient().contains(pointerPos)) {
+//                    PointerInfo info = new PointerInfo(window, pointerPos);
+//
+//                    fall2Child(info);
+//
+//                    return info;
+//                }
+//            }
+//        }
+//
+//        return new PointerInfo(null, null);
+//    }
+// END android-changed
+    
+    private void findEventSource(PointerInfo info) {
+        Component grabOwner = mouseGrabManager.getSyntheticGrabOwner();
+
+        if (grabOwner != null && grabOwner.isShowing()) {
+            info.position = convertPoint(info.src, info.position, grabOwner);
+            info.src = grabOwner;
+        } else {
+            //???AWT: rise2TopLevel(info);
+            //???AWT: fall2Child(info);
+        }
+    }
+
+ // BEGIN android-changed: AWT components not supported
+//    private void rise2TopLevel(PointerInfo info) {
+//        while (!(info.src instanceof Window)) {
+//            info.position.translate(info.src.x, info.src.y);
+//            info.src = info.src.parent;
+//        }
+//    }
+//
+//    private void fall2Child(PointerInfo info) {
+//        Insets insets = info.src.getInsets();
+//
+//        final Point pos = info.position;
+//        final int x = pos.x;
+//        final int y = pos.y;
+//        if ((x >= insets.left) && (y >= insets.top) &&
+//                (x < (info.src.w - insets.right)) &&
+//                (y < (info.src.h - insets.bottom)))
+//        {
+//            Component[] children = ((Container) info.src).getComponents();
+//
+//            for (Component child : children) {
+//                if (child.isShowing()) {
+//                    if (child.contains(x - child.getX(),
+//                            y - child.getY()))
+//                    {
+//                        info.src = child;
+//                        pos.translate(-child.x, -child.y);
+//
+//                        if (child instanceof Container) {
+//                            fall2Child(info);
+//                        }
+//
+//                        return;
+//                    }
+//                }
+//            }
+//        }
+//    }
+// END android-changed
+
+    private void dispatchButtonEvent(PointerInfo info, NativeEvent event) {
+        int button = event.getMouseButton();
+        long time = event.getTime();
+        int id = event.getEventId();
+        int index = button - 1;
+        boolean clickRequired = false;
+
+        propagateEvent(info, AWTEvent.MOUSE_EVENT_MASK,
+                       MouseListener.class, false);
+        if (id == MouseEvent.MOUSE_PRESSED) {
+            int clickInterval = toolkit.dispatcher.clickInterval;
+            mouseGrabManager.onMousePressed(info.src);
+            buttonPressed[index] = true;
+            clickCount[index] = (!deltaExceeded(index, info) &&
+                    ((time - lastPressTime[index]) <= clickInterval)) ?
+                    clickCount[index] + 1 : 1;
+            lastPressTime[index] = time;
+            lastPressPos[index] = info.position;
+        } else {
+            mouseGrabManager.onMouseReleased(info.src);
+            // set cursor back on synthetic mouse grab end:
+// BEGIN android-changed: AWT components not supported
+//            setCursor(findComponentUnderPointer().src);
+// END android-changed
+            if (buttonPressed[index]) {
+                buttonPressed[index] = false;
+                clickRequired = !deltaExceeded(index, info);
+            } else {
+                clickCount[index] = 0;
+            }
+        }
+        if (info.src.isIndirectlyEnabled()) {
+            final Point pos = info.position;
+            final int mod = event.getInputModifiers();
+            toolkit.getSystemEventQueueImpl().postEvent(
+                            new MouseEvent(info.src, id, time, mod, pos.x,
+                            pos.y, clickCount[index],
+                            event.getTrigger(), button));
+            if (clickRequired) {
+                toolkit.getSystemEventQueueImpl().postEvent(
+                            new MouseEvent(info.src,
+                            MouseEvent.MOUSE_CLICKED,
+                            time, mod, pos.x, pos.y,
+                            clickCount[index], false,
+                            button));
+            }
+        }
+    }
+
+    private boolean deltaExceeded(int index, PointerInfo info) {
+        final Point lastPos = lastPressPos[index];
+        if (lastPos == null) {
+            return true;
+        }
+        return ((Math.abs(lastPos.x - info.position.x) > clickDelta) ||
+                (Math.abs(lastPos.y - info.position.y) > clickDelta));
+    }
+
+    private void dispatchMotionEvent(PointerInfo info, NativeEvent event) {
+        propagateEvent(info, AWTEvent.MOUSE_MOTION_EVENT_MASK,
+                       MouseMotionListener.class, false);
+        final Point pos = info.position;
+        if ((lastUnderMotion != info.src) ||
+            !lastLocalPos.equals(pos)) {
+
+            lastUnderMotion = info.src;
+            lastLocalPos = pos;
+
+            if (info.src.isIndirectlyEnabled()) {
+                toolkit.getSystemEventQueueImpl().postEvent(
+                            new MouseEvent(info.src, event.getEventId(),
+                            event.getTime(),
+                            event.getInputModifiers(),
+                            pos.x, pos.y, 0, false));
+            }
+        }
+    }
+
+    MouseWheelEvent createWheelEvent(Component src, NativeEvent event,
+                                     Point where) {
+
+        Integer scrollAmountProperty =
+            (Integer)toolkit.getDesktopProperty("awt.wheelScrollingSize"); //$NON-NLS-1$
+        int amount = 1;
+        int type = MouseWheelEvent.WHEEL_UNIT_SCROLL;
+
+        if (scrollAmountProperty != null) {
+            amount = scrollAmountProperty.intValue();
+            if (amount == -1) {
+                type = MouseWheelEvent.WHEEL_BLOCK_SCROLL;
+                amount = 1;
+            }
+        }
+        return new MouseWheelEvent(src, event.getEventId(),
+                event.getTime(), event.getInputModifiers(),
+                where.x, where.y, 0, false, type, amount,
+                event.getWheelRotation());
+    }
+
+// BEGIN android-changed: AWT components not supported
+//    private void dispatchWheelEvent(Component src, NativeEvent event) {
+//        PointerInfo info = findComponentUnderPointer();
+//
+//        if (info.src == null) {
+//            info.src = src;
+//            info.position = event.getLocalPos();
+//        }
+//
+//        propagateEvent(info, AWTEvent.MOUSE_WHEEL_EVENT_MASK,
+//                       MouseWheelListener.class, true);
+//        if ((info.src != null) && info.src.isIndirectlyEnabled()) {
+//            toolkit.getSystemEventQueueImpl().postEvent(
+//                    createWheelEvent(info.src, event, info.position));
+//        }
+//    }
+// END android-changed
+
+    private PointerInfo propagateEvent(PointerInfo info, long mask,
+                                       Class<? extends EventListener> type, boolean pierceHW) {
+        Component src = info.src;
+        while ((src != null) &&
+               (src.isLightweight() || pierceHW) &&
+              !(src.isMouseEventEnabled(mask) ||
+               (src.getListeners(type).length > 0))) {
+
+            info.position.translate(src.x, src.y);
+// BEGIN android-changed: AWT components not supported
+//            src = src.parent;
+// END android-changed
+            info.src = src;
+        }
+
+        return info;
+    }
+
+// BEGIN android-changed: AWT components not supported
+//    Window findWindowAt(Point p) {
+//        NativeWindow nativeWindow =
+//            toolkit.getWindowFactory().getWindowFromPoint(p);
+//
+//        Window window = null;
+//        if (nativeWindow != null) {
+//            Component comp = toolkit.getComponentById(nativeWindow.getId());
+//
+//            if (comp != null) {
+//                window = comp.getWindowAncestor();
+//            }
+//        }
+//        return window;
+//    }
+// END android-changed
+
+    private class PointerInfo {
+
+        Component src;
+        Point position;
+
+        PointerInfo(Component src, Point position) {
+            this.src = src;
+            this.position = position;
+        }
+
+    }
+
+}
diff --git a/awt/java/awt/Paint.java b/awt/java/awt/Paint.java
new file mode 100644
index 0000000..f8732c8
--- /dev/null
+++ b/awt/java/awt/Paint.java
@@ -0,0 +1,52 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+
+/**
+ * The Paint interface provides possibility of generating 
+ * color patterns in device space for fill, draw, or stroke operations 
+ * in a Graphics2D.
+ */
+public interface Paint extends Transparency {
+    
+    /**
+     * Creates the PaintContext which is used to generate color 
+     * patterns for rendering operations of Graphics2D.
+     * 
+     * @param cm the ColorModel object, or null.
+     * @param deviceBounds the Rectangle represents the bounding box of
+     * device space for the graphics rendering operations.
+     * @param userBounds the Rectangle represents bounding box of
+     * user space for the graphics rendering operations.
+     * @param xform the AffineTransform for translation from user space 
+     * to device space.
+     * @param hints the RenderingHints preferences.
+     * 
+     * @return the PaintContext for generating color patterns.
+     */
+    PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
+            Rectangle2D userBounds, AffineTransform xform,
+            RenderingHints hints);
+}
diff --git a/awt/java/awt/PaintContext.java b/awt/java/awt/PaintContext.java
new file mode 100644
index 0000000..647de8b
--- /dev/null
+++ b/awt/java/awt/PaintContext.java
@@ -0,0 +1,64 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+
+/**
+ * The PaintContext interface determines the specific environment for
+ * generating color patterns in device space for fill, draw, or stroke 
+ * rendering operations using Graphics2D. This interface provides colors
+ * through the Raster object associated with the specific ColorModel 
+ * for Graphics2D rendering operations.
+ */
+public interface PaintContext {
+    
+    /**
+     * Releases the resources allocated for the operation.
+     */
+    void dispose();
+
+    /**
+     * Gets the color model.
+     * 
+     * @return the ColorModel object.
+     */
+    ColorModel getColorModel();
+
+    /**
+     * Gets the Raster which defines the colors of the specified rectangular 
+     * area for Graphics2D rendering operations.
+     * 
+     * @param x the X coordinate of the device space area for which 
+     * colors are generated.
+     * @param y the Y coordinate of the device space area for which 
+     * colors are generated.
+     * @param w the width of the device space area for which 
+     * colors are generated.
+     * @param h the height of the device space area for which 
+     * colors are generated.
+     * 
+     * @return the Raster object which contains the colors of the specified 
+     * rectangular area for Graphics2D rendering operations.
+     */
+    Raster getRaster(int x, int y, int w, int h);
+}
diff --git a/awt/java/awt/Point.java b/awt/java/awt/Point.java
new file mode 100644
index 0000000..99418ed
--- /dev/null
+++ b/awt/java/awt/Point.java
@@ -0,0 +1,195 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.Point2D;
+import java.io.Serializable;
+
+/**
+ * The Point class represents a point location with coordinates X, Y in 
+ * current coordinate system.
+ */
+public class Point extends Point2D implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -5276940640259749850L;
+
+    /** The X coordinate of Point. */
+    public int x;
+    
+    /** The Y coordinate of Point. */
+    public int y;
+
+    /**
+     * Instantiates a new point with (0, O) coordinates, the origin of 
+     * coordinate system.
+     */
+    public Point() {
+        setLocation(0, 0);
+    }
+
+    /**
+     * Instantiates a new point with (x, y) coordinates.
+     * 
+     * @param x the X coordinate of Point.
+     * @param y the Y coordinate of Point.
+     */
+    public Point(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Instantiates a new point, giving it the same locaion as
+     * the parameter p.
+     * 
+     * @param p the Point object giving the coordinates of the new point.
+     */
+    public Point(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Compares current Point with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the Object being compared is a Point 
+     * whose coordinates are equal to the coordinates of this 
+     * Point, otherwise false.
+     * 
+     * @see java.awt.geom.Point2D#equals(Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Point) {
+            Point p = (Point)obj;
+            return x == p.x && y == p.y;
+        }
+        return false;
+    }
+
+    /**
+     * Returns string representation of the current Point object.
+     * 
+     * @return a string representation of the current Point object.
+     */
+    @Override
+    public String toString() {
+        return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Gets X coordinate of Point as a double.
+     * 
+     * @return X coordinate of the point as a double.
+     * 
+     * @see java.awt.geom.Point2D#getX()
+     */
+    @Override
+    public double getX() {
+        return x;
+    }
+
+    /**
+     * Gets Y coordinate of Point as a double.
+     * 
+     * @return Y coordinate of the point as a double.
+     * 
+     * @see java.awt.geom.Point2D#getY()
+     */
+    @Override
+    public double getY() {
+        return y;
+    }
+
+    /**
+     * Gets the location of the Point as a new Point object.
+     * 
+     * @return a copy of the Point.
+     */
+    public Point getLocation() {
+        return new Point(x, y);
+    }
+
+    /**
+     * Sets the location of the Point to the same coordinates as p.
+     * 
+     * @param p the Point that gives the new location.
+     */
+    public void setLocation(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Sets the location of the Point to the coordinates X, Y.
+     * 
+     * @param x the X coordinate of the Point's new location.
+     * @param y the Y coordinate of the Point's new location.
+     */
+    public void setLocation(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Sets the location of Point to the specified double coordinates.
+     * 
+     * @param x the X the Point's new location.
+     * @param y the Y the Point's new location.
+     *  
+     * @see java.awt.geom.Point2D#setLocation(double, double)
+     */
+    @Override
+    public void setLocation(double x, double y) {
+        x = x < Integer.MIN_VALUE ? Integer.MIN_VALUE : x > Integer.MAX_VALUE ? Integer.MAX_VALUE : x;
+        y = y < Integer.MIN_VALUE ? Integer.MIN_VALUE : y > Integer.MAX_VALUE ? Integer.MAX_VALUE : y;
+        setLocation((int)Math.round(x), (int)Math.round(y));
+    }
+
+    /**
+     * Moves the Point to the specified (x, y) location.
+     * 
+     * @param x the X coordinate of the new location.
+     * @param y the Y coordinate of the new location. 
+     */
+    public void move(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Translates current Point moving it from the position (x, y) 
+     * to the new position given by (x+dx, x+dy) coordinates.
+     * 
+     * @param dx the horizontal delta - the Point is moved to this distance along
+     * X axis.
+     * @param dy the vertical delta - the Point is moved to this distance along
+     * Y axis.
+     */
+    public void translate(int dx, int dy) {
+        x += dx;
+        y += dy;
+    }
+
+}
+
diff --git a/awt/java/awt/Polygon.java b/awt/java/awt/Polygon.java
new file mode 100644
index 0000000..6f3fc97
--- /dev/null
+++ b/awt/java/awt/Polygon.java
@@ -0,0 +1,494 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.*;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Polygon class defines an closed area specified by n vertices and 
+ * n edges. The coordinates of the vertices are specified by x, y arrays.
+ * The edges are the line segments from the point (x[i], y[i]) to the point 
+ * (x[i+1], y[i+1]), for -1 < i < (n-1) plus the line segment from 
+ * the point (x[n-1], y[n-1]) to the point (x[0], y[0]) point. 
+ * The Polygon is empty if the number of vertices is zero.   
+ */
+public class Polygon implements Shape, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -6460061437900069969L;
+
+    /** The points buffer capacity. */
+    private static final int BUFFER_CAPACITY = 4;
+    
+    /** The number of Polygon vertices.*/
+    public int npoints;
+    
+    /** The array of X coordinates of the vertices. */
+    public int[] xpoints;
+    
+    /** The array of Y coordinates of the vertices. */
+    public int[] ypoints;
+    
+    /**  
+     * The smallest Rectangle that completely contains this Polygon. 
+     */
+    protected Rectangle bounds;
+
+    /*
+     * Polygon path iterator  
+     */
+    /**
+     * The internal Class Iterator.
+     */
+    class Iterator implements PathIterator {
+
+        /** The source Polygon object. */
+        public Polygon p;
+        
+        /** The path iterator transformation. */
+        public AffineTransform t;
+        
+        /** The current segmenet index. */
+        public int index;
+
+        /**
+         * Constructs a new Polygon.Iterator for the given polygon and transformation
+         * 
+         * @param at - the AffineTransform object to apply rectangle path
+         * @param p the p
+         */
+        public Iterator(AffineTransform at, Polygon p) {
+            this.p = p;
+            this.t = at;
+            if (p.npoints == 0) {
+                index = 1;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_EVEN_ODD;
+        }
+
+        public boolean isDone() {
+            return index > p.npoints;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.110=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
+            }
+            if (index == p.npoints) {
+                return SEG_CLOSE;
+            }
+            coords[0] = p.xpoints[index];
+            coords[1] = p.ypoints[index];
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return index == 0 ? SEG_MOVETO : SEG_LINETO;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.110=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.110")); //$NON-NLS-1$
+            }
+            if (index == p.npoints) {
+                return SEG_CLOSE;
+            }
+            coords[0] = p.xpoints[index];
+            coords[1] = p.ypoints[index];
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return index == 0 ? SEG_MOVETO : SEG_LINETO;
+        }
+    }
+
+    /**
+     * Instantiates a new empty polygon.
+     */
+    public Polygon() {
+        xpoints = new int[BUFFER_CAPACITY];
+        ypoints = new int[BUFFER_CAPACITY];
+    }
+
+    /**
+     * Instantiates a new polygon with the specified number of vertices,
+     * and the given arrays of x, y vertex coordinates. The length of 
+     * each coordinate array may not be less than the specified number of 
+     * vertices but may be greater. Only the first n elements are used from 
+     * each coordinate array.
+     * 
+     * @param xpoints the array of X vertex coordinates. 
+     * @param ypoints the array of Y vertex coordinates.
+     * @param npoints the number vertices of the polygon.
+     * @throws IndexOutOfBoundsException if the length of xpoints or ypoints
+     * is less than n.
+     * @throws NegativeArraySizeException if n is negative.
+     */
+    public Polygon(int[] xpoints, int[] ypoints, int npoints) {
+        if (npoints > xpoints.length || npoints > ypoints.length) {
+            // awt.111=Parameter npoints is greater than array length
+            throw new IndexOutOfBoundsException(Messages.getString("awt.111")); //$NON-NLS-1$
+        }
+        if (npoints < 0) {
+            // awt.112=Negative number of points
+            throw new NegativeArraySizeException(Messages.getString("awt.112")); //$NON-NLS-1$
+        }
+        this.npoints = npoints;
+        this.xpoints = new int[npoints];
+        this.ypoints = new int[npoints];
+        System.arraycopy(xpoints, 0, this.xpoints, 0, npoints);
+        System.arraycopy(ypoints, 0, this.ypoints, 0, npoints);
+    }
+
+    /**
+     * Resets the current Polygon to an empty Polygon. More precisely, 
+     * the number of Polygon vertices is set to zero, but x, y coordinates 
+     * arrays are not affected.  
+     */
+    public void reset() {
+        npoints = 0;
+        bounds = null;
+    }
+
+    /**
+     * Invalidates the data that depends on the vertex coordinates. 
+     * This method should be called after direct manipulations  
+     * of the x, y vertex coordinates arrays to avoid unpredictable 
+     * results of methods which rely on the bounding box.
+     */
+    public void invalidate() {
+        bounds = null;
+    }
+
+    /**
+     * Adds the point to the Polygon and updates the bounding box 
+     * accordingly.
+     * 
+     * @param px the X coordinate of the added vertex.
+     * @param py the Y coordinate of the added vertex.
+     */
+    public void addPoint(int px, int py) {
+        if (npoints == xpoints.length) {
+            int[] tmp;
+
+            tmp = new int[xpoints.length + BUFFER_CAPACITY];
+            System.arraycopy(xpoints, 0, tmp, 0, xpoints.length);
+            xpoints = tmp;
+
+            tmp = new int[ypoints.length + BUFFER_CAPACITY];
+            System.arraycopy(ypoints, 0, tmp, 0, ypoints.length);
+            ypoints = tmp;
+        }
+
+        xpoints[npoints] = px;
+        ypoints[npoints] = py;
+        npoints++;
+
+        if (bounds != null) {
+            bounds.setFrameFromDiagonal(
+                    Math.min(bounds.getMinX(), px),
+                    Math.min(bounds.getMinY(), py),
+                    Math.max(bounds.getMaxX(), px),
+                    Math.max(bounds.getMaxY(), py));
+        }
+    }
+
+    /**
+     * Gets the bounding rectangle of the Polygon. The bounding rectangle
+     * is the smallest rectangle which contains the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * 
+     * @see java.awt.Shape#getBounds()
+     */
+    public Rectangle getBounds() {
+        if (bounds != null) {
+            return bounds;
+        }
+        if (npoints == 0) {
+            return new Rectangle();
+        }
+
+        int bx1 = xpoints[0];
+        int by1 = ypoints[0];
+        int bx2 = bx1;
+        int by2 = by1;
+
+        for (int i = 1; i < npoints; i++) {
+            int x = xpoints[i];
+            int y = ypoints[i];
+            if (x < bx1) {
+                bx1 = x;
+            } else if (x > bx2) {
+                bx2 = x;
+            }
+            if (y < by1) {
+                by1 = y;
+            } else if (y > by2) {
+                by2 = y;
+            }
+        }
+
+        return bounds = new Rectangle(bx1, by1, bx2 - bx1, by2 - by1);
+    }
+
+    /**
+     * Gets the bounding rectangle of the Polygon. The bounding rectangle
+     * is the smallest rectangle which contains the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * 
+     * @deprecated Use getBounds() method.
+     */
+    @Deprecated
+    public Rectangle getBoundingBox() {
+        return getBounds();
+    }
+
+    /**
+     * Gets the Rectangle2D which represents Polygon bounds.
+     * The bounding rectangle is the smallest rectangle which contains 
+     * the Polygon.
+     * 
+     * @return the bounding rectangle of the Polygon.
+     * 
+     * @see java.awt.Shape#getBounds2D()
+     */
+    public Rectangle2D getBounds2D() {
+        return getBounds().getBounds2D();
+    }
+
+    /**
+     * Translates all vertices of Polygon the specified distances
+     * along X, Y axis.
+     * 
+     * @param mx the distance to translate horizontally.
+     * @param my the distance to translate vertically.
+     */
+    public void translate(int mx, int my) {
+        for (int i = 0; i < npoints; i++) {
+            xpoints[i] += mx;
+            ypoints[i] += my;
+        }
+        if (bounds != null) {
+            bounds.translate(mx, my);
+        }
+    }
+
+    /**
+     * Checks whether or not the point given by the coordinates x, y lies inside 
+     * the Polygon.
+     * 
+     * @param x the X coordinate of the point to check.
+     * @param y the Y coordinate of the point to check.
+     * 
+     * @return true, if the specified point lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @deprecated Use contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int x, int y) {
+        return contains((double) x, (double) y);
+    }
+
+    /**
+     * Checks whether or not the point given by the coordinates x, y lies inside 
+     * the Polygon.
+     * 
+     * @param x the X coordinate of the point to check.
+     * @param y the Y coordinate of the point to check.
+     * 
+     * @return true, if the specified point lies inside the Polygon,
+     * otherwise false.
+     */
+    public boolean contains(int x, int y) {
+        return contains((double) x, (double) y);
+    }
+
+    /**
+     * Checks whether or not the point with specified double coordinates 
+     * lies inside the Polygon.
+     * 
+     * @param x the X coordinate of the point to check.
+     * @param y the Y coordinate of the point to check.
+     * 
+     * @return true, if the point given by the double coordinates 
+     * lies inside the Polygon, otherwise false.
+     * 
+     * @see java.awt.Shape#contains(double, double)
+     */
+    public boolean contains(double x, double y) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, x, y));
+    }
+
+    /**
+     * Checks whether or not the rectangle determined by the parameters  
+     * [x, y, width, height] lies inside the Polygon.
+     * 
+     * @param x the X coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param y the Y coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param width the width of rectangle as a double.
+     * @param width the height of rectangle as a double.
+     * 
+     * @return true, if the specified rectangle lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @see java.awt.Shape#contains(double, double, double, double)
+     */
+    public boolean contains(double x, double y, double width, double height) {
+        int cross = Crossing.intersectShape(this, x, y, width, height);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    /**
+     * Checks whether or not the rectangle determined by the parameters  
+     * [x, y, width, height] intersects the interior of
+     * the Polygon.
+     * 
+     * @param x the X coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param y the Y coordinate of the rectangles's left upper 
+     * corner as a double.
+     * @param width the width of rectangle as a double.
+     * @param width the height of rectangle as a double.
+     * 
+     * @return true, if the specified rectangle intersects the interior of
+     * the Polygon, otherwise false.
+     * 
+     * @see java.awt.Shape#intersects(double, double, double, double)
+     */
+    public boolean intersects(double x, double y, double width, double height) {
+        int cross = Crossing.intersectShape(this, x, y, width, height);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    /**
+     * Checks whether or not the specified rectangle lies inside the Polygon.
+     * 
+     * @param rect the Rectangle2D object.
+     * 
+     * @return true, if the specified rectangle lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D)
+     */
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    /**
+     * Checks whether or not the specified Point lies inside the Polygon.
+     * 
+     * @param point the Point object.
+     * 
+     * @return true, if the specified Point lies inside the Polygon,
+     * otherwise false.
+     */
+    public boolean contains(Point point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    /**
+     * Checks whether or not the specified Point2D lies inside the Polygon.
+     * 
+     * @param point the Point2D object.
+     * 
+     * @return true, if the specified Point2D lies inside the Polygon,
+     * otherwise false.
+     * 
+     * @see java.awt.Shape#contains(java.awt.geom.Point2D)
+     */
+    public boolean contains(Point2D point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    /**
+     * Checks whether or not the interior of rectangle specified by 
+     * the Rectangle2D object intersects the interior of the Polygon.
+     * 
+     * @param rect the Rectangle2D object.
+     * 
+     * @return true, if the Rectangle2D intersects the interior of
+     * the Polygon, otherwise false.
+     * 
+     * @see java.awt.Shape#intersects(java.awt.geom.Rectangle2D)
+     */
+    public boolean intersects(Rectangle2D rect) {
+        return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    /**
+     * Gets the PathIterator object which gives the coordinates of 
+     * the polygon, transformed according to the specified AffineTransform.
+     * 
+     * @param t the specified AffineTransform object, or null.
+     * 
+     * @return PathIterator object for the Polygon.
+     * 
+     * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform)
+     */
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(t, this);
+    }
+
+    /**
+     * Gets the PathIterator object which gives the coordinates of 
+     * the polygon, transformed according to the specified AffineTransform.
+     * The flatness parameter is ignored.
+     * 
+     * @param t the specified AffineTransform object, or null.
+     * @param flatness the maximum number of the control points for 
+     * a given curve which varies from colinear before a subdivided curve 
+     * is replaced by a straight line connecting the endpoints. 
+     * This parameter is ignored for the Polygon class.
+     * 
+     * @return PathIterator object for the Polygon.
+     *  
+     * @see java.awt.Shape#getPathIterator(java.awt.geom.AffineTransform, double)
+     */
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new Iterator(t, this);
+    }
+
+}
+
diff --git a/awt/java/awt/Rectangle.java b/awt/java/awt/Rectangle.java
new file mode 100644
index 0000000..86c4dfc
--- /dev/null
+++ b/awt/java/awt/Rectangle.java
@@ -0,0 +1,686 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.Rectangle2D;
+import java.io.Serializable;
+
+/**
+ * The Rectangle class defines the rectangular area in terms of its
+ * upper left corner coordinates [x,y], its width, and its height.  
+ * A Rectangle specified by [x, y, width, height] parameters has an 
+ * outline path with corners at [x, y], [x + width,y], [x + width,y + height], 
+ * and [x, y + height]. 
+ * <br><br>
+ * The rectangle is empty if the width or height is negative or zero. 
+ * In this case the isEmpty method returns true.
+ */
+public class Rectangle extends Rectangle2D implements Shape, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -4345857070255674764L;
+
+    /** The X coordinate of the rectangle's left upper corner. */
+    public int x;
+    
+    /** The Y coordinate of the rectangle's left upper corner. */
+    public int y;
+    
+    /** The width of rectangle. */
+    public int width;
+    
+    /** The height of rectangle. */
+    public int height;
+
+    /**
+     * Instantiates a new rectangle with [0, 0] upper left corner coordinates,
+     * the width and the height are zero.
+     */
+    public Rectangle() {
+        setBounds(0, 0, 0, 0);
+    }
+
+    /**
+     * Instantiates a new rectangle whose upper left corner coordinates are
+     * given by the Point object (p.X and p.Y), and the width and 
+     * the height are zero. 
+     * 
+     * @param p the Point specifies the upper left corner coordinates of 
+     * the rectangle.
+     */
+    public Rectangle(Point p) {
+        setBounds(p.x, p.y, 0, 0);
+    }
+
+    /**
+      * Instantiates a new rectangle whose upper left corner coordinates are
+     * given by the Point object (p.X and p.Y), and the width and the height
+     * are given by Dimension object (d.width and d.height). 
+     * 
+     * @param p the Point specifies the upper left corner coordinates of 
+     * the rectangle.
+     * @param d the Dimention specifies the width and the height of the rectangle. 
+     */
+    public Rectangle(Point p, Dimension d) {
+        setBounds(p.x, p.y, d.width, d.height);
+    }
+
+    /**
+     * Instantiates a new rectangle determined by the upper left corner 
+     * coordinates (x, y), width and height.
+     * 
+     * @param x the X upper left corner coordinate of the rectangle.
+     * @param y the Y upper left corner coordinate of the rectangle.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle. 
+     */
+    public Rectangle(int x, int y, int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Instantiates a new rectangle with [0, 0] as its upper left 
+     * corner coordinates and the specified width and height.
+     * 
+     * @param width the width of rectangle.
+     * @param height the height of rectangle. 
+     */
+    public Rectangle(int width, int height) {
+        setBounds(0, 0, width, height);
+    }
+
+    /**
+     * Instantiates a new rectangle with the same coordinates 
+     * as the given source rectangle.
+     * 
+     * @param r the Rectangle object which parameters will be used for 
+     * instantiating a new Rectangle.
+     */
+    public Rectangle(Rectangle r) {
+        setBounds(r.x, r.y, r.width, r.height);
+    }
+/*
+    public Rectangle(Dimension d) {
+        setBounds(0, 0, d.width, d.height);
+    }
+*/
+    /**
+     * Gets the X coordinate of bound as a double.
+     * 
+     * @return the X coordinate of bound as a double.
+     *   
+     * @see java.awt.geom.RectangularShape#getX()
+     */
+    @Override
+    public double getX() {
+        return x;
+    }
+
+    /**
+     * Gets the Y coordinate of bound as a double.
+     * 
+     * @return the Y coordinate of bound as a double.
+     * 
+     * @see java.awt.geom.RectangularShape#getY()
+     */
+    @Override
+    public double getY() {
+        return y;
+    }
+
+    /**
+     * Gets the height of the rectangle as a double.
+     * 
+     * @return the height of the rectangle as a double. 
+     * 
+     * @see java.awt.geom.RectangularShape#getHeight()
+     */
+    @Override
+    public double getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the width of the rectangle as a double.
+     * 
+     * @return the width of the rectangle as a double.
+     *  
+     * @see java.awt.geom.RectangularShape#getWidth()
+     */
+    @Override
+    public double getWidth() {
+        return width;
+    }
+
+    /**
+     * Determines whether or not the rectangle is empty. The rectangle is empty if 
+     * its width or height is negative or zero.
+     * 
+     * @return true, if the rectangle is empty, otherwise false.
+     * 
+     * @see java.awt.geom.RectangularShape#isEmpty()
+     */
+    @Override
+    public boolean isEmpty() {
+        return width <= 0 || height <= 0;
+    }
+
+    /**
+     * Gets the size of a Rectangle as Dimention object.
+     * 
+     * @return a Dimention object which represents size of the rectangle.
+     */
+    public Dimension getSize() {
+        return new Dimension(width, height);
+    }
+
+    /**
+     * Sets the size of the Rectangle.
+     * 
+     * @param width the new width of the rectangle. 
+     * @param height the new height of the rectangle.
+     */
+    public void setSize(int width, int height) {
+        this.width = width;
+        this.height = height;
+    }
+
+    /**
+     * Sets the size of a Rectangle specified as Dimension object.
+     * 
+     * @param d a Dimension object which represents new size of a rectangle.
+     */
+    public void setSize(Dimension d) {
+        setSize(d.width, d.height);
+    }
+
+    /**
+     * Gets the location of a rectangle's upper left corner as a Point object.
+     * 
+     * @return the Point object with coordinates equal to the upper left corner 
+     * of the rectangle.
+     */
+    public Point getLocation() {
+        return new Point(x, y);
+    }
+
+    /**
+     * Sets the location of the rectangle in terms of its upper left 
+     * corner coordinates X and Y.
+     * 
+     * @param x the X coordinate of the rectangle's upper left corner.
+     * @param y the Y coordinate of the rectangle's upper left corner.
+     */
+    public void setLocation(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Sets the location of a rectangle using a Point object to give the 
+     * coordinates of the upper left corner.
+     * 
+     * @param p the Point object which represents the new upper left corner 
+     * coordinates of rectangle.  
+     */
+    public void setLocation(Point p) {
+        setLocation(p.x, p.y);
+    }
+
+    /**
+     * Moves a rectangle to the new location by moving its upper left corner
+     * to the point with coordinates X and Y.
+     * 
+     * @param x the new X coordinate of the rectangle's upper left corner.
+     * @param y the new Y coordinate of the rectangle's upper left corner.
+     * 
+     * @deprecated Use setLocation(int, int) method.
+     */
+    @Deprecated
+    public void move(int x, int y) {
+        setLocation(x, y);
+    }
+
+    /**
+     * Sets the rectangle to be the nearest rectangle with integer coordinates 
+     * bounding the rectangle defined by the double-valued parameters.
+     * 
+     * @param x the X coordinate of the upper left corner of the double-valued
+     * rectangle to be bounded.
+     * @param y the Y coordinate of the upper left corner of the double-valued
+     * rectangle to be bounded.
+     * @param width the width of the rectangle to be bounded.
+     * @param height the height of the rectangle to be bounded.      
+     * 
+     * @see java.awt.geom.Rectangle2D#setRect(double, double, double, double)
+     */
+    @Override
+    public void setRect(double x, double y, double width, double height) {
+        int x1 = (int)Math.floor(x);
+        int y1 = (int)Math.floor(y);
+        int x2 = (int)Math.ceil(x + width);
+        int y2 = (int)Math.ceil(y + height);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Sets a new size for the rectangle.
+     * 
+     * @param width the rectangle's new width.
+     * @param height the rectangle's new height.
+     * 
+     * @deprecated use the setSize(int, int) method.
+     */
+    @Deprecated
+    public void resize(int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Resets the bounds of a rectangle to the specified x, y, width and height 
+     * parameters.
+     * 
+     * @param x the new X coordinate of the upper left corner.
+     * @param y the new Y coordinate of the upper left corner.
+     * @param width the new width of rectangle.
+     * @param height the new height of rectangle. 
+     * 
+     * @deprecated use setBounds(int, int, int, int) method
+     */
+    @Deprecated
+    public void reshape(int x, int y, int width, int height) {
+        setBounds(x, y, width, height);
+    }
+
+    /**
+     * Gets bounds of the rectangle as a new Rectangle object.
+     *  
+     * @return the Rectangle object with the same bounds as 
+     * the original rectangle. 
+     * 
+     * @see java.awt.geom.RectangularShape#getBounds()
+     */
+    @Override
+    public Rectangle getBounds() {
+        return new Rectangle(x, y, width, height);
+    }
+
+    /**
+     * Gets the bounds of the original rectangle as a Rectangle2D object.
+     *  
+     * @return the Rectangle2D object which represents the bounds of 
+     * the original rectangle. 
+     * 
+     * @see java.awt.geom.Rectangle2D#getBounds2D()
+     */
+    @Override
+    public Rectangle2D getBounds2D() {
+        return getBounds();
+    }
+
+    /**
+     * Sets the bounds of a rectangle to the specified x, y, width, and height 
+     * parameters.
+     * 
+     * @param x the X coordinate of the upper left corner.
+     * @param y the Y coordinate of the upper left corner.
+     * @param width the width of rectangle.
+     * @param height the height of rectangle. 
+     */
+    public void setBounds(int x, int y, int width, int height) {
+        this.x = x;
+        this.y = y;
+        this.height = height;
+        this.width = width;
+    }
+
+    /**
+     * Sets the bounds of the rectangle to match the bounds of the
+     * Rectangle object sent as a parameter.
+     * 
+     * @param r the Rectangle object which specifies the new bounds. 
+     */
+    public void setBounds(Rectangle r) {
+        setBounds(r.x, r.y, r.width, r.height);
+    }
+
+    /**
+     * Enlarges the rectangle by moving each corner outward from the 
+     * center by a distance of dx horizonally and a distance of dy 
+     * vertically. Specifically, changes a rectangle with 
+     * [x, y, width, height] parameters to 
+     * a rectangle with [x-dx, y-dy, width+2*dx, height+2*dy]
+     * parameters. 
+     *   
+     * @param dx the horizontal distance to move each corner coordinate.
+     * @param dy the vertical distance to move each corner coordinate.
+     */
+    public void grow(int dx, int dy) {
+        x -= dx;
+        y -= dy;
+        width += dx + dx;
+        height += dy + dy;
+    }
+
+    /**
+     * Moves a rectangle a distance of mx along the x coordinate axis 
+     * and a distance of my along y coordinate axis.
+     * 
+     * @param mx the horizontal translation increment.
+     * @param my the vertical translation increment.
+     */
+    public void translate(int mx, int my) {
+        x += mx;
+        y += my;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified point.
+     * 
+     * @param px the X coordinate of the new point to be covered by the rectangle.
+     * @param py the Y coordinate of the new point to be covered by the rectangle.
+     */
+    public void add(int px, int py) {
+        int x1 = Math.min(x, px);
+        int x2 = Math.max(x + width, px);
+        int y1 = Math.min(y, py);
+        int y2 = Math.max(y + height, py);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified point with the
+     * new point given as a Point object.
+     * 
+     * @param p the Point object that specifies the new point to 
+     * be covered by the rectangle.
+     */
+    public void add(Point p) {
+        add(p.x, p.y);
+    }
+
+    /**
+     * Adds a new rectangle to the original rectangle, the result is an union of
+     * the specified specified rectangle and original rectangle.
+     * 
+     * @param r the Rectangle which is added to the original rectangle. 
+     */
+    public void add(Rectangle r) {
+        int x1 = Math.min(x, r.x);
+        int x2 = Math.max(x + width, r.x + r.width);
+        int y1 = Math.min(y, r.y);
+        int y2 = Math.max(y + height, r.y + r.height);
+        setBounds(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Determines whether or not the point with specified coordinates [px, py] 
+     * is within the bounds of the rectangle.
+     * 
+     * @param px the X coordinate of point.
+     * @param py the Y coordinate of point.
+     * 
+     * @return true, if the point with specified coordinates [px, py] is 
+     * within the bounds of the rectangle, otherwise false.
+     */
+    public boolean contains(int px, int py) {
+        if (isEmpty()) {
+            return false;
+        }
+        if (px < x || py < y) {
+            return false;
+        }
+        px -= x;
+        py -= y;
+        return px < width && py < height;
+    }
+
+    /**
+     * Determines whether or not the point given as a Point object 
+     * is within the bounds of the rectangle.
+     * 
+     * @param p the Point object
+     * 
+     * @return true, if the point p is within the bounds of the 
+     * rectangle, otherwise false.
+     */
+    public boolean contains(Point p) {
+        return contains(p.x, p.y);
+    }
+
+    /**
+     * Determines whether or not the rectangle specified by [rx, ry, rw, rh] 
+     * parameters is located inside the original rectangle.
+     * 
+     * @param rx the X coordinate of the rectangle to compare.
+     * @param ry the Y coordinate of the rectangle to compare.
+     * @param rw the width of the rectangle to compare.
+     * @param rh the height of the rectangle to compare.
+     * 
+     * @return true, if a rectangle with [rx, ry, rw, rh] parameters is entirely
+     * contained in the original rectangle, otherwise false.
+     */
+    public boolean contains(int rx, int ry, int rw, int rh) {
+        return contains(rx, ry) && contains(rx + rw - 1, ry + rh - 1);
+    }
+
+    /**
+     * Compares whether or not the rectangle specified by the Rectangle object
+     * is located inside the original rectangle.
+     * 
+     * @param r the Rectangle object.
+     * 
+     * @return true, if the rectangle specified by Rectangle object is entirely
+     * contained in the original rectangle, otherwise false.
+     */
+    public boolean contains(Rectangle r) {
+        return contains(r.x, r.y, r.width, r.height);
+    }
+
+    /**
+     * Compares whether or not a point with specified coordinates [px, py] belongs 
+     * to a rectangle.
+     * 
+     * @param px the X coordinate of a point.
+     * @param py the Y coordinate of a point.
+     * 
+     * @return true, if a point with specified coordinates [px, py] belongs 
+     * to a rectangle, otherwise false.
+     * 
+     * @deprecated use contains(int, int) method.
+     */
+    @Deprecated
+    public boolean inside(int px, int py) {
+        return contains(px, py);
+    }
+
+    /**
+     * Returns the intersection of the original rectangle with the 
+     * specified Rectangle2D.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return the Rectangle2D object that is the result of intersecting 
+     * the original rectangle with the specified Rectangle2D.
+     * 
+     * @see java.awt.geom.Rectangle2D#createIntersection(java.awt.geom.Rectangle2D)
+     */
+    @Override
+    public Rectangle2D createIntersection(Rectangle2D r) {
+        if (r instanceof Rectangle) {
+            return intersection((Rectangle) r);
+        }
+        Rectangle2D dst = new Rectangle2D.Double();
+        Rectangle2D.intersect(this, r, dst);
+        return dst;
+    }
+
+    /**
+     * Returns the intersection of the original rectangle with the 
+     * specified rectangle. An empty rectangle is returned if there is no
+     * intersection.
+     * 
+     * @param r the Rectangle object.
+     * 
+     * @return the Rectangle object is result of the original rectangle with the 
+     * specified rectangle. 
+     */
+    public Rectangle intersection(Rectangle r) {
+        int x1 = Math.max(x, r.x);
+        int y1 = Math.max(y, r.y);
+        int x2 = Math.min(x + width, r.x + r.width);
+        int y2 = Math.min(y + height, r.y + r.height);
+        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Determines whether or not the original rectangle intersects 
+     * the specified rectangle.
+     * 
+     * @param r the Rectangle object.
+     * 
+     * @return true, if the two rectangles overlap; otherwise false.
+     */
+    public boolean intersects(Rectangle r) {
+        return !intersection(r).isEmpty();
+    }
+
+    /**
+     * Determines where the specified Point is located with respect to 
+     * the rectangle. This method computes whether the point is to the 
+     * right or to the left of the rectangle and whether it is above 
+     * or below the rectangle, and packs the result into an int by 
+     * using a binary OR operation with the following masks:
+     * <ul>
+     *<li>Rectangle2D.OUT_LEFT</li>
+     *<li>Rectangle2D.OUT_TOP</li>
+     *<li>Rectangle2D.OUT_RIGHT</li>
+     *<li>Rectangle2D.OUT_BOTTOM</li>
+     *</ul>
+     *
+     * If the rectangle is empty, all masks are set, and if the 
+     * point is inside the rectangle, none are set.
+     * 
+     * @param px the X coordinate of the specified point.
+     * @param py the Y coordinate of the specified point.
+     * 
+     * @return the location of the Point relative to the rectangle 
+     * as the result of logical OR operation with all out masks.
+     * 
+     * @see java.awt.geom.Rectangle2D#outcode(double, double)
+     */
+    @Override
+    public int outcode(double px, double py) {
+        int code = 0;
+
+        if (width <= 0) {
+            code |= OUT_LEFT | OUT_RIGHT;
+        } else
+            if (px < x) {
+                code |= OUT_LEFT;
+            } else
+                if (px > x + width) {
+                    code |= OUT_RIGHT;
+                }
+
+        if (height <= 0) {
+            code |= OUT_TOP | OUT_BOTTOM;
+        } else
+            if (py < y) {
+                code |= OUT_TOP;
+            } else
+                if (py > y + height) {
+                    code |= OUT_BOTTOM;
+                }
+
+        return code;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified Rectangle2D.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return the union of the original and the specified Rectangle2D.
+     * 
+     * @see java.awt.geom.Rectangle2D#createUnion(java.awt.geom.Rectangle2D)
+     */
+    @Override
+    public Rectangle2D createUnion(Rectangle2D r) {
+        if (r instanceof Rectangle) {
+            return union((Rectangle)r);
+        }
+        Rectangle2D dst = new Rectangle2D.Double();
+        Rectangle2D.union(this, r, dst);
+        return dst;
+    }
+
+    /**
+     * Enlarges the rectangle to cover the specified rectangle.
+     * 
+     * @param r the Rectangle.
+     * 
+     * @return the union of the original and the specified rectangle.
+     */
+    public Rectangle union(Rectangle r) {
+        Rectangle dst = new Rectangle(this);
+        dst.add(r);
+        return dst;
+    }
+
+    /**
+     * Compares the original Rectangle with the specified object.
+     * 
+     * @param obj the specified Object for comparison.
+     * 
+     * @return true, if the specified Object is a rectangle with the 
+     * same dimensions as the original rectangle, otherwise false.
+     * 
+     * @see java.awt.geom.Rectangle2D#equals(Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Rectangle) {
+            Rectangle r = (Rectangle)obj;
+            return r.x == x && r.y == y && r.width == width && r.height == height;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of the rectangle; the string contains 
+     * [x, y, width, height] parameters of the rectangle.
+     * 
+     * @return the string representation of the rectangle.
+     */
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. It could be obtained in the following way
+        // System.out.println(new Rectangle().toString())
+        return getClass().getName() + "[x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$
+            ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+}
+
diff --git a/awt/java/awt/RenderingHints.java b/awt/java/awt/RenderingHints.java
new file mode 100644
index 0000000..4957884
--- /dev/null
+++ b/awt/java/awt/RenderingHints.java
@@ -0,0 +1,601 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The RenderingHints class represents preferences for the rendering algorithms. 
+ * The preferences are arbitrary and can be specified by Map objects or by 
+ * key-value pairs. 
+ */
+public class RenderingHints implements Map<Object, Object>, Cloneable {
+    
+    /**
+     * The Constant KEY_ALPHA_INTERPOLATION - alpha interpolation rendering 
+     * hint key. 
+     */
+    public static final Key KEY_ALPHA_INTERPOLATION = new KeyImpl(1);
+    
+    /** 
+     * The Constant VALUE_ALPHA_INTERPOLATION_DEFAULT - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT = new KeyValue(KEY_ALPHA_INTERPOLATION);
+    
+    /** 
+     * The Constant VALUE_ALPHA_INTERPOLATION_SPEED - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_SPEED = new KeyValue(KEY_ALPHA_INTERPOLATION);
+    
+    /** 
+     * The Constant VALUE_ALPHA_INTERPOLATION_QUALITY - alpha interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY = new KeyValue(KEY_ALPHA_INTERPOLATION);
+
+    /** 
+     * The Constant KEY_ANTIALIASING - antialiasing rendering 
+     * hint key. 
+     */
+    public static final Key KEY_ANTIALIASING = new KeyImpl(2);
+    
+    /**
+     * The Constant VALUE_ANTIALIAS_DEFAULT - antialiasing
+     * rendering hint value. 
+     */
+    public static final Object VALUE_ANTIALIAS_DEFAULT = new KeyValue(KEY_ANTIALIASING);
+    
+    /** 
+     * The Constant VALUE_ANTIALIAS_ON - antialiasing
+     * rendering hint value.
+     */
+    public static final Object VALUE_ANTIALIAS_ON = new KeyValue(KEY_ANTIALIASING);
+    
+    /**
+     * The Constant VALUE_ANTIALIAS_OFF - antialiasing
+     * rendering hint value.
+     */
+    public static final Object VALUE_ANTIALIAS_OFF = new KeyValue(KEY_ANTIALIASING);
+
+    /** 
+     * The Constant KEY_COLOR_RENDERING  - color rendering 
+     * hint key.
+     */
+    public static final Key KEY_COLOR_RENDERING = new KeyImpl(3);
+    
+    /**
+     * The Constant VALUE_COLOR_RENDER_DEFAULT - color
+     * rendering hint value. 
+     */
+    public static final Object VALUE_COLOR_RENDER_DEFAULT = new KeyValue(KEY_COLOR_RENDERING);
+    
+    /** 
+     * The Constant VALUE_COLOR_RENDER_SPEED  - color
+     * rendering hint value. 
+     */
+    public static final Object VALUE_COLOR_RENDER_SPEED = new KeyValue(KEY_COLOR_RENDERING);
+    
+    /** 
+     * The Constant VALUE_COLOR_RENDER_QUALITY - color
+     * rendering hint value.
+     */
+    public static final Object VALUE_COLOR_RENDER_QUALITY = new KeyValue(KEY_COLOR_RENDERING);
+
+    /**
+     *  The Constant KEY_DITHERING  - dithering
+     * rendering hint key.
+     */
+    public static final Key KEY_DITHERING = new KeyImpl(4);
+    
+    /**
+     * The Constant VALUE_DITHER_DEFAULT - dithering
+     * rendering hint value.
+     */
+    public static final Object VALUE_DITHER_DEFAULT = new KeyValue(KEY_DITHERING);
+    
+    /** 
+     * The Constant VALUE_DITHER_DISABLE - dithering
+     * rendering hint value.
+     */
+    public static final Object VALUE_DITHER_DISABLE = new KeyValue(KEY_DITHERING);
+    
+    /** 
+     * The Constant VALUE_DITHER_DISABLE - dithering
+     * rendering hint value.
+     */
+    public static final Object VALUE_DITHER_ENABLE = new KeyValue(KEY_DITHERING);
+
+    /** 
+     * The Constant KEY_FRACTIONALMETRICS - fractional metrics
+     * rendering hint key.
+     */
+    public static final Key KEY_FRACTIONALMETRICS = new KeyImpl(5);
+    
+    /**
+     * The Constant VALUE_FRACTIONALMETRICS_DEFAULT - fractional metrics
+     * rendering hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_DEFAULT = new KeyValue(KEY_FRACTIONALMETRICS);
+    
+    /**
+     * The Constant VALUE_FRACTIONALMETRICS_ON - fractional metrics
+     * rendering hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_ON = new KeyValue(KEY_FRACTIONALMETRICS);
+    
+    /**
+     *  The Constant VALUE_FRACTIONALMETRICS_OFF - fractional metrics
+     * rendering hint value.
+     */
+    public static final Object VALUE_FRACTIONALMETRICS_OFF = new KeyValue(KEY_FRACTIONALMETRICS);
+
+    /** 
+     * The Constant KEY_INTERPOLATION - interpolation
+     * rendering hint key.
+     */
+    public static final Key KEY_INTERPOLATION = new KeyImpl(6);
+    
+    /** 
+     * The Constant VALUE_INTERPOLATION_BICUBIC - interpolation
+     * rendering hint value. 
+     */
+    public static final Object VALUE_INTERPOLATION_BICUBIC = new KeyValue(KEY_INTERPOLATION);
+    
+    /**
+     * The Constant VALUE_INTERPOLATION_BILINEAR - interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_INTERPOLATION_BILINEAR = new KeyValue(KEY_INTERPOLATION);
+    
+    /** The Constant VALUE_INTERPOLATION_NEAREST_NEIGHBOR - interpolation
+     * rendering hint value.
+     */
+    public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR = new KeyValue(KEY_INTERPOLATION);
+
+    /**
+     * The Constant KEY_RENDERING - rendering hint key.
+     */
+    public static final Key KEY_RENDERING = new KeyImpl(7);
+    
+    /** 
+     * The Constant VALUE_RENDER_DEFAULT - rendering hint value. 
+     */
+    public static final Object VALUE_RENDER_DEFAULT = new KeyValue(KEY_RENDERING);
+    
+    /** 
+     * The Constant VALUE_RENDER_SPEED - rendering hint value. 
+     */
+    public static final Object VALUE_RENDER_SPEED = new KeyValue(KEY_RENDERING);
+    
+    /** 
+     * The Constant VALUE_RENDER_QUALITY - rendering hint value. 
+     */
+    public static final Object VALUE_RENDER_QUALITY = new KeyValue(KEY_RENDERING);
+
+    /** 
+     * The Constant KEY_STROKE_CONTROL - stroke control hint key. 
+     */
+    public static final Key KEY_STROKE_CONTROL = new KeyImpl(8);
+    
+    /** 
+     * The Constant VALUE_STROKE_DEFAULT - stroke hint value. 
+     */
+    public static final Object VALUE_STROKE_DEFAULT = new KeyValue(KEY_STROKE_CONTROL);
+    
+    /** 
+     * The Constant VALUE_STROKE_NORMALIZE - stroke hint value. 
+     */
+    public static final Object VALUE_STROKE_NORMALIZE = new KeyValue(KEY_STROKE_CONTROL);
+    
+    /** 
+     * The Constant VALUE_STROKE_PURE - stroke hint value. 
+     */
+    public static final Object VALUE_STROKE_PURE = new KeyValue(KEY_STROKE_CONTROL);
+
+    /** 
+     * The Constant KEY_TEXT_ANTIALIASING - text antialiasing hint key. 
+     */
+    public static final Key KEY_TEXT_ANTIALIASING = new KeyImpl(9);
+    
+    /**
+     *  The Constant VALUE_TEXT_ANTIALIAS_DEFAULT - text antialiasing hint key. 
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT = new KeyValue(KEY_TEXT_ANTIALIASING);
+    
+    /**
+     * The Constant VALUE_TEXT_ANTIALIAS_ON - text antialiasing hint key.
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_ON = new KeyValue(KEY_TEXT_ANTIALIASING);
+    
+    /**
+     * The Constant VALUE_TEXT_ANTIALIAS_OFF - text antialiasing hint key. 
+     */
+    public static final Object VALUE_TEXT_ANTIALIAS_OFF = new KeyValue(KEY_TEXT_ANTIALIASING);
+
+    /** The map. */
+    private HashMap<Object, Object> map = new HashMap<Object, Object>();
+    
+    /**
+     * Instantiates a new rendering hints object from specified Map object with defined
+     * key/value pairs or null for empty RenderingHints. 
+     * 
+     * @param map the Map object with defined key/value pairs or null for
+     * empty RenderingHints. 
+     */
+    public RenderingHints(Map<Key, ?> map) {
+        super();
+        if (map != null) {
+            putAll(map);
+        }
+    }
+
+    /**
+     * Instantiates a new rendering hints object with the specified key/value pair.
+     * 
+     * @param key the key of hint property.
+     * @param value the value of hint property.
+     */
+    public RenderingHints(Key key, Object value) {
+        super();
+        put(key, value);
+    }
+
+    /**
+     * Adds the properties represented by key/value pairs from the specified
+     * RenderingHints object to current object.
+     * 
+     * @param hints the RenderingHints to be added.
+     */
+    public void add(RenderingHints hints) {
+        map.putAll(hints.map);
+    }
+
+    /**
+     * Puts the specified value to the specified key. Neither the key nor 
+     * the value can be null.
+     * 
+     * @param key the rendering hint key.
+     * @param value the rendering hint value. 
+     * 
+     * @return the previous rendering hint value assigned to the key or null.
+     * 
+     */
+    public Object put(Object key, Object value) {
+        if (!((Key)key).isCompatibleValue(value)) {
+            throw new IllegalArgumentException();
+        }
+
+        return map.put(key, value);
+    }
+
+    /**
+     * Removes the specified key and corresponding value from 
+     * the RenderingHints object.
+     * 
+     * @param key the specified hint key to be removed.
+     * 
+     * @return the object of previous rendering hint value which is 
+     * assigned to the specified key, or null.
+     */
+    public Object remove(Object key) {
+        return map.remove(key);
+    }
+
+    /**
+     * Gets the value assigned to the specified key.
+     * 
+     * @param key the rendering hint key.
+     * 
+     * @return the object assigned to the specified key.
+     */
+    public Object get(Object key) {
+        return map.get(key);
+    }
+
+    /**
+     * Returns a set of rendering hints keys for current RenderingHints object.
+     * 
+     * @return the set of rendering hints keys. 
+     */
+    public Set<Object> keySet() {
+        return map.keySet();
+    }
+
+    /**
+     * Returns a set of Map.Entry objects which contain current RenderingHint
+     * key/value pairs.
+     * 
+     * @return the a set of mapped RenderingHint key/value pairs.
+     */
+    public Set<Map.Entry<Object, Object>> entrySet() {
+        return map.entrySet();
+    }
+
+    /**
+     * Puts all of the preferences from the specified Map into 
+     * the current RenderingHints object. These mappings replace 
+     * all existing preferences.
+     * 
+     * @param m the specified Map of preferences.
+     */
+    public void putAll(Map<?, ?> m) {
+        if (m instanceof RenderingHints) {
+            map.putAll(((RenderingHints) m).map);
+        } else {
+            Set<?> entries = m.entrySet();
+
+            if (entries != null){
+                Iterator<?> it = entries.iterator();
+                while (it.hasNext()) {
+                    Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next();
+                    Key key = (Key) entry.getKey();
+                    Object val = entry.getValue();
+                    put(key, val);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a Collection of values contained in current RenderingHints object.
+     * 
+     * @return the Collection of RenderingHints's values.
+     */
+    public Collection<Object> values() {
+        return map.values();
+    }
+
+    /**
+     * Checks whether or not current RenderingHints object contains at least one
+     * the value which is equal to the specified Object.
+     * 
+     * @param value the specified Object.
+     * 
+     * @return true, if the specified object is assigned to at least one
+     * RenderingHint's key, false otherwise.
+     */
+    public boolean containsValue(Object value) {
+        return map.containsValue(value);
+    }
+
+    /**
+     * Checks whether or not current RenderingHints object contains the key
+     * which is equal to the specified Object.
+     * 
+     * @param key the specified Object.
+     * 
+     * @return true, if the RenderingHints object contains the specified Object
+     * as a key, false otherwise.
+     * 
+     */
+    public boolean containsKey(Object key) {
+        if (key == null) {
+            throw new NullPointerException();
+        }
+
+        return map.containsKey(key);
+    }
+
+    /**
+     * Checks whether or not the RenderingHints object contains any 
+     * key/value pairs.
+     * 
+     * @return true, if the RenderingHints object is empty, false otherwise.
+     */
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    /**
+     * Clears the RenderingHints of all key/value pairs.
+     */
+    public void clear() {
+        map.clear();
+    }
+
+    /**
+     * Returns the number of key/value pairs in the RenderingHints.
+     * 
+     * @return the number of key/value pairs.
+     */
+    public int size() {
+        return map.size();
+    }
+
+    /**
+     * Compares the RenderingHints object with the specified object.
+     * 
+     * @param o the specified Object to be compaired.
+     * 
+     * @return true, if the Object is a Map whose key/value pairs 
+     * match this RenderingHints' key/value pairs, 
+     * false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Map)) {
+            return false;
+        }
+
+        Map<?, ?> m = (Map<?, ?>)o;
+        Set<?> keys = keySet();
+        if (!keys.equals(m.keySet())) {
+            return false;
+        }
+
+        Iterator<?> it = keys.iterator();
+        while (it.hasNext()) {
+            Key key = (Key)it.next();
+            Object v1 = get(key);
+            Object v2 = m.get(key);
+            if (!(v1==null?v2==null:v1.equals(v2))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the hash code for this RenderingHints object.
+     * 
+     * @return the hash code for this RenderingHints object.
+     */
+    @Override
+    public int hashCode() {
+        return map.hashCode();
+    }
+
+    /**
+     * Returns the clone of the RenderingHints object with the same contents.
+     * 
+     * @return the clone of the RenderingHints instance.
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object clone() {
+        RenderingHints clone = new RenderingHints(null);
+        clone.map = (HashMap<Object, Object>)this.map.clone();
+        return clone;
+    }
+
+    /**
+     * Returns the string representation of the RenderingHints object.
+     * 
+     * @return the String object which represents RenderingHints object. 
+     */
+    @Override
+    public String toString() {
+        return "RenderingHints["+map.toString()+"]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * The RenderingHints.Key class is abstract and defines a base type for 
+     * all RenderingHints keys.
+     */
+    public abstract static class Key {
+        
+        /** The key. */
+        private final int key;
+
+        /**
+         * Instantiates a new key with unique int identifier. 
+         * No two objects of the same subclass with the same integer key
+         * can be instantiated. 
+         * 
+         * @param key the unique key.
+         */
+        protected Key(int key) {
+            this.key = key;
+        }
+
+        /**
+         * Compares the Key object with the specified object.
+         * 
+         * @param o the specified Object to be compaired.
+         * 
+         * @return true, if the Key is equal to the specified object, 
+         * false otherwise.
+         */
+        @Override
+        public final boolean equals(Object o) {
+            return this == o;
+        }
+
+        /**
+         * Returns the hash code for this Key object.
+         * 
+         * @return the hash code for this Key object.
+         */
+        @Override
+        public final int hashCode() {
+            return System.identityHashCode(this);
+        }
+
+        /**
+         * Returns int unique key with which this Key object has been 
+         * instantiated.
+         * 
+         * @return the int unique key with which this Key object has been 
+         * instantiated.
+         */
+        protected final int intKey() {
+            return key;
+        }
+
+        /**
+         * Checks whether or not specified value is compatible with the Key.
+         * 
+         * @param val the Object.
+         * 
+         * @return true, if the specified value is compatible with the Key,
+         * false otherwise.
+         */
+        public abstract boolean isCompatibleValue(Object val);
+    }
+
+    /**
+     * Private implementation of Key class.
+     */
+    private static class KeyImpl extends Key {
+
+        /**
+         * Instantiates a new key impl.
+         * 
+         * @param key the key
+         */
+        protected KeyImpl(int key) {
+            super(key);
+        }
+
+        @Override
+        public boolean isCompatibleValue(Object val) {
+            if (!(val instanceof KeyValue)) {
+                return false;
+            }
+
+            return ((KeyValue)val).key == this;
+        }
+    }
+
+    /**
+     * Private class KeyValue is used as value for Key class instance.
+     */
+    private static class KeyValue {
+        
+        /** The key. */
+        private final Key key;
+
+        /**
+         * Instantiates a new key value.
+         * 
+         * @param key the key
+         */
+        protected KeyValue(Key key) {
+            this.key = key;
+        }
+    }
+}
diff --git a/awt/java/awt/Shape.java b/awt/java/awt/Shape.java
new file mode 100644
index 0000000..3dbad25
--- /dev/null
+++ b/awt/java/awt/Shape.java
@@ -0,0 +1,162 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The Shape interface defines a geometric shape defined by a boundary 
+ * (outline) path. The path outline can be accessed through a 
+ * PathIterator object. The Shape 
+ * interface provides methods for obtaining the bounding box (which is 
+ * the smallest rectangle containing the shape and for obtaining a PathIterator 
+ * object for current Shape, as well as utility methods which 
+ * determine if the Shape contains or intersects a Rectangle or contains a Point.
+ */
+public interface Shape {
+    
+    /**
+     * Checks whether or not the point with specified coordinates lies inside 
+     * the Shape.
+     * 
+     * @param x the X coordinate.
+     * @param y the Y coordinate.
+     * 
+     * @return true, if the specified coordinates lie inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(double x, double y);
+
+    /**
+     * Checks whether or not the rectangle with specified 
+     * [x, y, width, height] parameters lies inside the Shape.
+     * 
+     * @param x the X double coordinate of the rectangle's upper left 
+     * corner.
+     * @param y the Y double coordinate of the rectangle's upper left 
+     * corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle.
+     * 
+     * @return true, if the specified rectangle lies inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(double x, double y, double w, double h);
+
+    /**
+     * Checks whether or not the specified Point2D lies inside the Shape.
+     * 
+     * @param point the Point2D object.
+     * 
+     * @return true, if the specified Point2D lies inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(Point2D point);
+
+    /**
+     * Checks whether or not the specified rectangle lies inside the Shape.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return true, if the specified rectangle lies inside the Shape,
+     * otherwise false.
+     */
+    public boolean contains(Rectangle2D r);
+
+    /**
+     * Gets the bounding rectangle of the Shape. The bounding rectangle
+     * is the smallest rectangle which contains the Shape.
+     * 
+     * @return the bounding rectangle of the Shape.
+     */
+    public Rectangle getBounds();
+
+    /**
+     * Gets the Rectangle2D which represents Shape bounds.
+     * The bounding rectangle is the smallest rectangle which contains 
+     * the Shape.
+     * 
+     * @return the bounding rectangle of the Shape.
+     */
+    public Rectangle2D getBounds2D();
+
+    /**
+     * Gets the PathIterator object of the Shape which provides 
+     * access to the shape's boundary modified 
+     * by the specified AffineTransform.
+     * 
+     * @param at the specified AffineTransform object, or null.
+     * 
+     * @return PathIterator object for the Shape.
+     */
+    public PathIterator getPathIterator(AffineTransform at);
+
+    /**
+     * Gets the PathIterator object of the Shape which provides 
+     * access to the coordinates of the shapes boundary modified 
+     * by the specified AffineTransform. The flatness parameter
+     * defines the amount of subdivision of the curved segments and
+     * specifies the maximum distance which every point on the 
+     * unflattened transformed curve can deviate from the returned 
+     * flattened path segments.  
+     * 
+     * @param at the specified AffineTransform object, or null.
+     * @param flatness the maximum number of the control points for 
+     * a given curve which varies from colinear before a subdivided 
+     * curve is replaced by a straight line connecting the endpoints. 
+     * 
+     * @return PathIterator object for the Shape.
+     */
+    public PathIterator getPathIterator(AffineTransform at, double flatness);
+
+    /**
+     * Checks whether or not the interior of rectangular specified by 
+     * [x, y, width, height] parameters intersects the interior of
+     * the Shape.
+     * 
+     * @param x the X double coordinate of the rectangle's upper left
+     * corner.
+     * @param y the Y double coordinate of the rectangle's upper left 
+     * corner.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle.
+     * 
+     * @return true, if the rectangle specified by 
+     * [x, y, width, height] parameters intersects the interior of
+     * the Shape, otherwise false.
+     * 
+     */
+    public boolean intersects(double x, double y, double w, double h);
+
+    /**
+     * Checks whether or not the interior of rectangl specified by 
+     * Rectangle2D object intersects the interior of the Shape.
+     * 
+     * @param r the Rectangle2D object.
+     * 
+     * @return true, if the Rectangle2D intersects the interior of
+     * the Shape, otherwise false.
+     */
+    public boolean intersects(Rectangle2D r);
+}
diff --git a/awt/java/awt/Stroke.java b/awt/java/awt/Stroke.java
new file mode 100644
index 0000000..e6d683d
--- /dev/null
+++ b/awt/java/awt/Stroke.java
@@ -0,0 +1,47 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The Stroke interface gives a pen style to be used by the 
+ * Graphics2D interface. It provides a means for getting a stroked version 
+ * of a shape, which is the version that is suitable for drawing via 
+ * the Graphics2D interface. Stroking a shape gives the shape's outline
+ * a width or drawing style. 
+ * <p>
+ * The Draw methods from Graphics2D interface should use the Stroke object for 
+ * rendering the shape's outline. The stroke should be set by 
+ * setStroke(java.awt.Stroke) method of the Graphics2D interface. 
+ * @see java.awt.Graphics2D#setStroke(java.awt.Stroke)
+ */
+public interface Stroke {
+    
+    /**
+     * Creates the stroked shape, which is the version that is suitable for drawing via 
+     * the Graphics2D interface. Stroking a shape gives the shape's outline
+     * a width or drawing style.
+     * 
+     * @param p the original shape.
+     * 
+     * @return the stroked shape.
+     */
+    public Shape createStrokedShape(Shape p);
+}
diff --git a/awt/java/awt/Toolkit.java b/awt/java/awt/Toolkit.java
new file mode 100644
index 0000000..0c066b2
--- /dev/null
+++ b/awt/java/awt/Toolkit.java
@@ -0,0 +1,1338 @@
+/*
+ *  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 java.awt;
+
+import java.awt.event.AWTEventListener;
+import java.awt.event.AWTEventListenerProxy;
+import java.awt.event.InputEvent;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.peer.FontPeer;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+import org.apache.harmony.awt.ChoiceStyle;
+import org.apache.harmony.awt.ComponentInternals;
+import org.apache.harmony.awt.ContextStorage;
+import org.apache.harmony.awt.ReadOnlyIterator;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.CreationParams;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+import org.apache.harmony.awt.wtk.NativeCursor;
+
+import org.apache.harmony.awt.wtk.NativeEventQueue;
+import org.apache.harmony.awt.wtk.NativeEventThread;
+import org.apache.harmony.awt.wtk.ShutdownWatchdog;
+import org.apache.harmony.awt.wtk.Synchronizer;
+import org.apache.harmony.awt.wtk.WTK;
+
+/**
+ * The Toolkit class is the representation of the platform-specific 
+ * Abstract Window Toolkit implementation. Toolkit's subclasses 
+ * are used to bind the various components to particular native 
+ * toolkit implementations.
+ */
+public abstract class Toolkit {
+    
+    /** The Constant RECOURCE_PATH. */
+    private static final String RECOURCE_PATH = "org.apache.harmony.awt.resources.AWTProperties"; //$NON-NLS-1$
+    
+    /** The Constant properties. */
+    private static final ResourceBundle properties = loadResources(RECOURCE_PATH);
+    
+    /** The dispatcher. */
+    Dispatcher dispatcher;
+
+    /** The system event queue core. */
+    private EventQueueCore systemEventQueueCore;
+
+    /** The dispatch thread. */
+    EventDispatchThread dispatchThread;
+
+    /** The native thread. */
+    NativeEventThread nativeThread;
+
+    /** The awt events manager. */
+    protected AWTEventsManager awtEventsManager;
+
+    /**
+     * The Class AWTTreeLock.
+     */
+    private class AWTTreeLock {
+    }
+
+    /** The awt tree lock. */
+    final Object awtTreeLock = new AWTTreeLock();
+
+    /** The synchronizer. */
+    private final Synchronizer synchronizer = ContextStorage.getSynchronizer();
+
+    /** The shutdown watchdog. */
+    final ShutdownWatchdog shutdownWatchdog = new ShutdownWatchdog();
+
+    /** The auto number. */
+    final AutoNumber autoNumber = new AutoNumber();
+
+    /** The event type lookup. */
+    final AWTEvent.EventTypeLookup eventTypeLookup = new AWTEvent.EventTypeLookup();
+
+    /** The b dynamic layout set. */    
+    private boolean bDynamicLayoutSet = true;
+
+    /** The set of desktop properties that user set directly. */
+    private final HashSet<String> userPropSet = new HashSet<String>();
+
+    /** The desktop properties. */
+    protected Map<String, Object> desktopProperties;
+
+    /** The desktop props support. */
+    protected PropertyChangeSupport desktopPropsSupport;
+
+    /**
+     * For this component the native window is being created
+     * It is used in the callback-driven window creation
+     * (e.g. on Windows in the handler of WM_CREATE event)
+     * to establish the connection between this component
+     * and its native window.
+     */
+    private Object recentNativeWindowComponent;
+
+    /** The wtk. */
+    private WTK wtk;
+
+    /**
+     * The Class ComponentInternalsImpl.
+     */
+    protected final class ComponentInternalsImpl extends ComponentInternals {
+
+        /**
+         * Shutdown.
+         */
+        @Override
+        public void shutdown() {
+            dispatchThread.shutdown();
+        }
+       
+        /**
+         * Sets the desktop property to the specified value and fires a property 
+         * change event.  
+         * 
+         * @param name the name of property.
+         * @param value the new value of property.
+         */
+        @Override
+        public void setDesktopProperty(String name, Object value) {
+            Toolkit.this.setDesktopProperty(name, value);
+        }
+    }
+
+
+    /**
+     * A lot of methods must throw HeadlessException
+     * if <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
+     * 
+     * @throws HeadlessException the headless exception
+     */
+    static void checkHeadless() throws HeadlessException {
+        if (GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance())
+            throw new HeadlessException();
+    }
+
+    /**
+     * Lock awt.
+     */
+    final void lockAWT() {
+        synchronizer.lock();
+    }
+
+    /**
+     * Static lock awt.
+     */
+    static final void staticLockAWT() {
+        ContextStorage.getSynchronizer().lock();
+    }
+
+    /**
+     * Unlock awt.
+     */
+    final void unlockAWT() {
+        synchronizer.unlock();
+    }
+
+    /**
+     * Static unlock awt.
+     */
+    static final void staticUnlockAWT() {
+        ContextStorage.getSynchronizer().unlock();
+    }    
+
+    /**
+     * InvokeAndWait under AWT lock. W/o this method system can hang up.
+     * Added to support modality (Dialog.show() & PopupMenu.show()) from
+     * not event dispatch thread. Use in other cases is not recommended.
+     *
+     * Still can be called only for whole API methods that
+     * cannot be called from other classes API methods.
+     * Examples:
+     *      show() for modal dialogs    - correct, only user can call it,
+     *                                      directly or through setVisible(true)
+     *      setBounds() for components  - incorrect, setBounds()
+     *                                      can be called from layoutContainer()
+     *                                      for layout managers
+     * 
+     * @param runnable the runnable
+     * 
+     * @throws InterruptedException the interrupted exception
+     * @throws InvocationTargetException the invocation target exception
+     */
+    final void unsafeInvokeAndWait(Runnable runnable) throws InterruptedException,
+            InvocationTargetException {
+        synchronizer.storeStateAndFree();
+        try {
+            EventQueue.invokeAndWait(runnable);
+        } finally {
+            synchronizer.lockAndRestoreState();
+        }
+    }
+
+    /**
+     * Gets the synchronizer.
+     * 
+     * @return the synchronizer
+     */
+    final Synchronizer getSynchronizer() {
+        return synchronizer;
+    }
+
+    /**
+     * Gets the wTK.
+     * 
+     * @return the wTK
+     */
+    final WTK getWTK() {
+        return wtk;
+    }
+
+    /**
+     * Gets the property with the specified key and default value. 
+     * This method returns the defValue if the property is not found. 
+     * 
+     * @param propName the name of property.
+     * @param defVal the default value.
+     * 
+     * @return the property value.
+     */
+    public static String getProperty(String propName, String defVal) {
+        if (propName == null) {
+            // awt.7D=Property name is null
+            throw new NullPointerException(Messages.getString("awt.7D")); //$NON-NLS-1$
+        }
+        staticLockAWT();
+        try {
+            String retVal = null;
+            if (properties != null) {
+                try {
+                    retVal = properties.getString(propName);
+                } catch (MissingResourceException e) {
+                } catch (ClassCastException e) {
+                }
+            }
+            return (retVal == null) ? defVal : retVal;
+        } finally {
+            staticUnlockAWT();
+        }
+    }
+    
+    /**
+     * Gets the default Toolkit.
+     * 
+     * @return the default Toolkit
+     */
+    public static Toolkit getDefaultToolkit() {
+        synchronized (ContextStorage.getContextLock()) {
+            if (ContextStorage.shutdownPending()) {
+                return null;
+            }
+            Toolkit defToolkit = ContextStorage.getDefaultToolkit();
+            if (defToolkit != null) {
+                return defToolkit;
+            }
+            staticLockAWT();
+            try {
+                defToolkit = GraphicsEnvironment.isHeadless() ?
+                        new HeadlessToolkit() : new ToolkitImpl();
+                ContextStorage.setDefaultToolkit(defToolkit);
+                return defToolkit;
+            } finally {
+                staticUnlockAWT();
+            }
+            //TODO: read system property named awt.toolkit
+            //and create an instance of the specified class,
+            //by default use ToolkitImpl
+        }
+    }
+    
+    /**
+     * Gets the default Font.
+     * 
+     * @return the derault Font for Toolkit.
+     */
+    Font getDefaultFont() {
+        return wtk.getSystemProperties().getDefaultFont();
+    }
+    
+    /**
+     * Load resources.
+     * 
+     * @param path the path
+     * 
+     * @return the resource bundle
+     */
+    private static ResourceBundle loadResources(String path) {
+        try {
+            return ResourceBundle.getBundle(path);
+        } catch (MissingResourceException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Gets the wTK class name.
+     * 
+     * @return the wTK class name
+     */
+    private static String getWTKClassName() {
+        return "com.android.internal.awt.AndroidWTK";
+    }
+
+    /**
+     * Gets the component by id.
+     * 
+     * @param id the id
+     * 
+     * @return the component by id
+     */
+    Component getComponentById(long id) {
+        if (id == 0) {
+            return null;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the GraphicsFactory.
+     * 
+     * @return the GraphicsFactory object.
+     */
+    public GraphicsFactory getGraphicsFactory() {
+        return wtk.getGraphicsFactory();
+    }
+
+    /**
+     * Instantiates a new toolkit.
+     */
+    public Toolkit() {        
+        init();
+    }
+
+    /**
+     * Inits AWT.
+     */
+    protected void init() {
+        lockAWT();
+        try {
+            ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
+            new EventQueue(this); // create the system EventQueue
+            dispatcher = new Dispatcher(this);
+            final String className = getWTKClassName();
+            desktopProperties = new HashMap<String, Object>();
+            desktopPropsSupport = new PropertyChangeSupport(this);
+            awtEventsManager = new AWTEventsManager();
+            dispatchThread = new EventDispatchThread(this, dispatcher);
+            nativeThread = new NativeEventThread();
+            NativeEventThread.Init init = new NativeEventThread.Init() {
+                public WTK init() {
+                    wtk = createWTK(className);
+                    wtk.getNativeEventQueue().setShutdownWatchdog(shutdownWatchdog);
+                    synchronizer.setEnvironment(wtk, dispatchThread);
+                    ContextStorage.setWTK(wtk);
+                    return wtk;
+                }
+            };
+            nativeThread.start(init);
+            dispatchThread.start();
+            wtk.getNativeEventQueue().awake();
+        } finally {
+            unlockAWT();
+        }
+    }
+    
+    /**
+     * Synchronizes this toolkit's graphics.
+     */
+    public abstract void sync();
+
+    /**
+     * Returns the construction status of a specified image that is being created.
+     * 
+     * @param a0 the image to be checked.
+     * @param a1 the width of scaled image for which the status is being checked, or -1.
+     * @param a2 the height of scaled image for which the status is being checked, or -1.
+     * @param a3 the ImageObserver object to be notified while 
+     * the image is being prepared.
+     * 
+     * @return the ImageObserver flags which give the current state of the image data.
+     */
+    public abstract int checkImage(Image a0, int a1, int a2, ImageObserver a3);
+   
+    /**
+     * Creates the image with the specified ImageProducer.
+     * 
+     * @param a0 the ImageProducer to be used for image creation.
+     * 
+     * @return the image with the specified ImageProducer.
+     */
+    public abstract Image createImage(ImageProducer a0);
+
+    /**
+     * Creates the image from the specified byte array, offset and length.
+     * The byte array should contain data with image format supported by 
+     * Toolkit such as JPEG, GIF, or PNG.  
+     * 
+     * @param a0 the byte array with the image data.
+     * @param a1 the offset of the beggining the image data in the byte array.
+     * @param a2 the length of the image data in the byte array.
+     * 
+     * @return the created Image.
+     */
+    public abstract Image createImage(byte[] a0, int a1, int a2);
+
+    /**
+     * Creates the image using image data from the specified URL.
+     * 
+     * @param a0 the URL for extracting image data.
+     * 
+     * @return the Image.
+     */
+    public abstract Image createImage(URL a0);
+
+    /**
+     * Creates the image using image data from the specified file.
+     * 
+     * @param a0 the file name which contains image data of supported format.
+     * 
+     * @return the Image.
+     */
+    public abstract Image createImage(String a0);
+
+    /**
+     * Gets the color model.
+     * 
+     * @return the ColorModel of Toolkit's screen.
+     * 
+     * @throws HeadlessException if the 
+     * GraphicsEnvironment.isHeadless() method returns true.
+     */
+    public abstract ColorModel getColorModel() throws HeadlessException;
+    
+    /**
+     * Gets the screen device metrics for the specified font.
+     * 
+     * @param font the Font.
+     * 
+     * @return the FontMetrics for the specified Font.
+     * 
+     * @deprecated Use getLineMetrics method from Font class.
+     */
+        
+    @Deprecated
+    public abstract FontMetrics getFontMetrics(Font font);
+
+    /**
+     * Prepares the specified image for rendering on the screen with the
+     * specified size.
+     * 
+     * @param a0 the Image to be prepared.
+     * @param a1 the width of the screen representation or -1 for the current screen.
+     * @param a2 the height of the screen representation or -1 for the current screen.
+     * @param a3 the ImageObserver object to be notified as soon as 
+     * the image is prepared.
+     * 
+     * @return true, if image is fully prepared; false otherwise.
+     */
+    public abstract boolean prepareImage(Image a0, int a1, int a2, ImageObserver a3);
+
+    /**
+     * Creates an audio beep.
+     */
+    public abstract void beep();
+
+    /**
+     * Returns the array of font names which are available in this Toolkit.
+     * 
+     * @return the array of font names which are available in this Toolkit.
+     * 
+     * @deprecated use GraphicsEnvironment.getAvailableFontFamilyNames() method.
+     */
+    @Deprecated
+    public abstract String[] getFontList();
+    
+    /**
+     * Gets the the Font implementation using the specified peer 
+     * interface.
+     * 
+     * @param a0 the Font name to be implemented.
+     * @param a1 the the font style: PLAIN, BOLD, ITALIC.
+     * 
+     * @return the FontPeer implementation of the specified Font.
+     * 
+     * @deprecated use java.awt.GraphicsEnvironment.getAllFonts method.
+     */
+
+    @Deprecated
+    protected abstract FontPeer getFontPeer(String a0, int a1);
+
+    /**
+     * Gets the image from the specified file which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG); this method 
+     * should return the same Image for multiple calls of this method with 
+     * the same image file name.
+     * 
+     * @param a0 the file name which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG).
+     * 
+     * @return the Image.
+     */
+    public abstract Image getImage(String a0);
+
+    /**
+     * Gets the image from the specified URL which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG); this method 
+     * should return the same Image for multiple calls of this method with 
+     * the same image URL.
+     * 
+     * @param a0 the URL which contains image data in
+     * a supported image format (such as JPEG, GIF, or PNG).
+     * 
+     * @return the Image.
+     */
+    public abstract Image getImage(URL a0);
+
+    /**
+     * Gets the screen resolution.
+     * 
+     * @return the screen resolution.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public abstract int getScreenResolution() throws HeadlessException;
+
+    /**
+     * Gets the screen size.
+     * 
+     * @return a Dimension object containing the width and height of
+     * the screen.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public abstract Dimension getScreenSize() throws HeadlessException;
+
+    /**
+     * Gets the EventQueue instance without checking access.
+     * 
+     * @return the system EventQueue.
+     */
+    protected abstract EventQueue getSystemEventQueueImpl();
+
+    /**
+     * Returns a map of text attributes for the abstract level description 
+     * of the specified input method highlight, or null if no mapping is found. 
+     *  
+     * @param highlight the InputMethodHighlight.
+     * 
+     * @return the Map<java.awt.font. text attribute,?>
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public abstract Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException;
+
+    /**
+     * Map input method highlight impl.
+     * 
+     * @param highlight the highlight
+     * 
+     * @return the map<java.awt.font. text attribute,?>
+     * 
+     * @throws HeadlessException the headless exception
+     */
+    Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(
+            InputMethodHighlight highlight) throws HeadlessException {
+        HashMap<java.awt.font.TextAttribute, ?> map = new HashMap<java.awt.font.TextAttribute, Object>();
+        wtk.getSystemProperties().mapInputMethodHighlight(highlight, map);
+        return Collections.<java.awt.font.TextAttribute, Object> unmodifiableMap(map);
+    }
+
+    /**
+     * Adds the specified PropertyChangeListener listener for the specified
+     * property.
+     * 
+     * @param propName the property name for which the specified PropertyChangeListener
+     * will be added. 
+     * @param l the PropertyChangeListener object.
+     */
+    public void addPropertyChangeListener(String propName, PropertyChangeListener l) {
+        lockAWT();
+        try {
+            if (desktopProperties.isEmpty()) {
+                initializeDesktopProperties();
+            }
+        } finally {
+            unlockAWT();
+        }
+        if (l != null) { // there is no guarantee that null listener will not be added
+            desktopPropsSupport.addPropertyChangeListener(propName, l);
+        }
+    }
+
+    /**
+     * Returns an array of the property change listeners registered with
+     * this Toolkit.
+     * 
+     * @return an array of the property change listeners registered with
+     * this Toolkit. 
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        return desktopPropsSupport.getPropertyChangeListeners();
+    }
+
+    /**
+     * Returns an array of the property change listeners registered with
+     * this Toolkit for notification regarding the specified property.
+     * 
+     * @param propName the property name for which the PropertyChangeListener
+     * was registered.
+     * 
+     * @return the array of PropertyChangeListeners registered for the specified 
+     * property name.
+     */
+    public PropertyChangeListener[] getPropertyChangeListeners(String propName) {
+        return desktopPropsSupport.getPropertyChangeListeners(propName);
+    }
+
+    /**
+     * Removes the specified property change listener registered for the
+     * specified property name.
+     * 
+     * @param propName the property name.
+     * @param l the PropertyChangeListener registered for the specified property name.
+     */
+    public void removePropertyChangeListener(String propName, PropertyChangeListener l) {
+        desktopPropsSupport.removePropertyChangeListener(propName, l);
+    }
+    
+    /**
+     * Creates a custom cursor with the specified Image, hot spot, and cursor
+     * description.
+     * 
+     * @param img the image of activated cursor.
+     * @param hotSpot the Point giving the coordinates of the cursor's hot spot. 
+     * @param name the cursor description.
+     * 
+     * @return the cursor with the specified Image, hot spot, and cursor
+     * description.
+     * 
+     * @throws IndexOutOfBoundsException if the hot spot values are outside  
+     * the bounds of the cursor.
+     * @throws HeadlessException if isHeadless() method of GraphicsEnvironment
+     * class returns true.
+     */
+    public Cursor createCustomCursor(Image img, Point hotSpot, String name)
+            throws IndexOutOfBoundsException, HeadlessException {
+        lockAWT();
+        try {
+            int w = img.getWidth(null), x = hotSpot.x;
+            int h = img.getHeight(null), y = hotSpot.y;
+            if (x < 0 || x >= w || y < 0 || y >= h) {
+                // awt.7E=invalid hotSpot
+                throw new IndexOutOfBoundsException(Messages.getString("awt.7E")); //$NON-NLS-1$
+            }
+            return new Cursor(name, img, hotSpot);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the supported cursor dimension which is closest to the 
+     * specified width and height. If the Toolkit only supports a single 
+     * cursor size, this method should return the supported cursor size.
+     * If custom cursor is not supported, a dimension of 0, 0 should be
+     * returned.
+     * 
+     * @param prefWidth the preffered cursor width.
+     * @param prefHeight the preffered cursor height.
+     * 
+     * @return the supported cursor dimension which is closest to the 
+     * specified width and height.
+     * 
+     * @throws HeadlessException if GraphicsEnvironment.isHeadless() 
+     * returns true.
+     */
+    public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getCursorFactory().getBestCursorSize(prefWidth, prefHeight);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the value for the specified desktop property. 
+     * 
+     * @param propName the property name.
+     * 
+     * @return the Object that is the property's value.
+     */
+    public final Object getDesktopProperty(String propName) {
+        lockAWT();
+        try {
+            if (desktopProperties.isEmpty()) {
+                initializeDesktopProperties();
+            }
+            if (propName.equals("awt.dynamicLayoutSupported")) { //$NON-NLS-1$
+                // dynamicLayoutSupported is special case
+                return Boolean.valueOf(isDynamicLayoutActive());
+            }
+            Object val = desktopProperties.get(propName);
+            if (val == null) {
+                // try to lazily load prop value
+                // just for compatibility, our lazilyLoad is empty
+                val = lazilyLoadDesktopProperty(propName);
+            }
+            return val;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the locking key state for the specified key.
+     * 
+     * @param a0 the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, 
+     * or VK_KANA_LOCK.
+     * 
+     * @return true if the specified key code is in the locked state,
+     * false otherwise.
+     * 
+     * @throws UnsupportedOperationException if the state of this key 
+     * can't be retrieved, or if the keyboard doesn't have this key.
+     * @throws NotImplementedException if this method is not implemented.
+     */
+    public boolean getLockingKeyState(int a0) throws UnsupportedOperationException, org.apache.harmony.luni.util.NotImplementedException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return true;
+    }
+
+    /**
+     * Returns the maximum number of colors which the Toolkit supports for
+     * custom cursor.
+     * 
+     * @return the maximum cursor colors.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public int getMaximumCursorColors() throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getCursorFactory().getMaximumCursorColors();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the menu shortcut key mask.
+     *
+     * @return the menu shortcut key mask.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public int getMenuShortcutKeyMask() throws HeadlessException {
+        lockAWT();
+        try {
+            return InputEvent.CTRL_MASK;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the screen insets.
+     * 
+     * @param gc the GraphicsConfiguration.
+     * 
+     * @return the insets of this toolkit.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
+        if (gc == null) {
+            throw new NullPointerException();
+        }
+        lockAWT();
+        try {
+            return new Insets(0, 0, 0, 0); //TODO: get real screen insets
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the system EventQueue instance. 
+     * If the default implementation of checkAwtEventQueueAccess is used,
+     * then this results of a call to the security manager's checkPermission
+     * method with an AWTPermission("accessEventQueue") permission.
+     * 
+     * @return the system EventQueue instance.
+     */
+    public final EventQueue getSystemEventQueue() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkAwtEventQueueAccess();
+        }
+        return getSystemEventQueueImpl();
+    }
+
+    /** 
+     * Gets the system event queue core.
+     * 
+     * @return the system event queue core
+     */
+    EventQueueCore getSystemEventQueueCore() {
+        return systemEventQueueCore;
+    }
+    
+    /**
+     * Sets the system event queue core.
+     * 
+     * @param core the new system event queue core
+     */
+    void setSystemEventQueueCore(EventQueueCore core) {
+        systemEventQueueCore = core;
+    }
+
+    /**
+     * Initialize the desktop properties.
+     */
+    protected void initializeDesktopProperties() {
+        lockAWT();
+        try {
+            wtk.getSystemProperties().init(desktopProperties);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if dynamic layout of Containers is active or not.
+     * 
+     * @return true, if is dynamic layout of Containers is active,
+     * false otherwise.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public boolean isDynamicLayoutActive() throws HeadlessException {
+        lockAWT();
+        try {
+            // always return true
+            return true;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+
+    /**
+     * Returns if the layout of Containers is checked dynamically during resizing,
+     * or statically after resizing is completed. 
+     * 
+     * @return true, if if the layout of Containers is checked dynamically during 
+     * resizing; false, if the layout of Containers is checked statically after 
+     * resizing is completed. 
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    protected boolean isDynamicLayoutSet() throws HeadlessException {
+        lockAWT();
+        try {
+            return bDynamicLayoutSet;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Checks if the specified frame state is supported by Toolkit or not.
+     * 
+     * @param state the frame state.
+     * 
+     * @return true, if frame state is supported; false othrwise.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public boolean isFrameStateSupported(int state) throws HeadlessException {
+        lockAWT();
+        try {
+            return wtk.getWindowFactory().isWindowStateSupported(state);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Loads the value of the desktop property with the specified property name.
+     * 
+     * @param propName the property name.
+     * 
+     * @return the desktop property values.
+     */
+    protected Object lazilyLoadDesktopProperty(String propName) {
+        return null;
+    }
+
+    /**
+     * Loads the current system color values to the specified array.
+     * 
+     * @param colors the array where the current system color values 
+     * are written by this method.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    protected void loadSystemColors(int[] colors) throws HeadlessException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the value of the desktop property with the specified name.
+     * 
+     * @param propName the property's name.
+     * @param value the property's value.
+     */
+    protected final void setDesktopProperty(String propName, Object value) {
+        Object oldVal;
+        lockAWT();
+        try {
+            oldVal = getDesktopProperty(propName);
+            userPropSet.add(propName);
+            desktopProperties.put(propName, value);
+        } finally {
+            unlockAWT();
+        }
+        desktopPropsSupport.firePropertyChange(propName, oldVal, value);
+    }
+
+    /**
+     * Sets the layout state, whether the Container layout is checked 
+     * dynamically during resizing, or statically after resizing is completed. 
+     * 
+     * @param dynamic the new dynamic layout state - if true the layout of 
+     * Containers is checked dynamically during resizing, if false -
+     * statically after resizing is completed.
+     * 
+     * @throws HeadlessException if the GraphicsEnvironment.isHeadless()
+     * method returns true.
+     */
+    public void setDynamicLayout(boolean dynamic) throws HeadlessException {
+        lockAWT();
+        try {
+            bDynamicLayoutSet = dynamic;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Sets the locking key state for the specified key code.
+     * 
+     * @param a0 the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, 
+     * or VK_KANA_LOCK.
+     * @param a1 the state - true to set the specified key code to the locked state,
+     * false - to unlock it.
+     * 
+     * @throws UnsupportedOperationException if the state of this key 
+     * can't be set, or if the keyboard doesn't have this key.
+     * @throws NotImplementedException if this method is not implemented.
+     */
+    public void setLockingKeyState(int a0, boolean a1) throws UnsupportedOperationException, org.apache.harmony.luni.util.NotImplementedException {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
+        }
+        return;
+    }
+
+
+    /**
+     * On queue empty.
+     */
+    void onQueueEmpty() {
+        throw new RuntimeException("Not implemented!");
+    }
+
+    /**
+     * Creates the wtk.
+     * 
+     * @param clsName the cls name
+     * 
+     * @return the wTK
+     */
+    private WTK createWTK(String clsName) {
+        WTK newWTK = null;
+        try {
+            newWTK = (WTK) Class.forName(clsName).newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return newWTK;
+    }
+
+    /**
+     * Connect the component to its native window
+     * @param winId - id of native window just created
+     */
+    boolean onWindowCreated(long winId) {
+        return false;
+    }
+
+    /**
+     * Gets the native event queue.
+     * 
+     * @return the native event queue
+     */
+    NativeEventQueue getNativeEventQueue() {
+        return wtk.getNativeEventQueue();
+    }
+
+    /**
+     * Returns a shared instance of implementation of org.apache.harmony.awt.wtk.NativeCursor
+     * for current platform for
+     * 
+     * @param type - Java Cursor type
+     * 
+     * @return new instance of implementation of NativeCursor
+     */
+    NativeCursor createNativeCursor(int type) {
+        return wtk.getCursorFactory().getCursor(type);
+    }
+
+    /**
+     * Returns a shared instance of implementation of org.apache.harmony.awt.wtk.NativeCursor
+     * for current platform for custom cursor
+     * 
+     * @param img the img
+     * @param hotSpot the hot spot
+     * @param name the name
+     * 
+     * @return new instance of implementation of NativeCursor
+     */
+    NativeCursor createCustomNativeCursor(Image img, Point hotSpot, String name) {
+        return wtk.getCursorFactory().createCustomCursor(img, hotSpot.x, hotSpot.y);
+    }
+
+    /**
+     * Adds an AWTEventListener to the Toolkit to listen for events
+     * of types corresponding to bits in the specified event mask. 
+     * Event masks are defined in AWTEvent class.
+     * 
+     * @param listener the AWTEventListener.
+     * @param eventMask he bitmask of event types.
+     */
+    public void addAWTEventListener(AWTEventListener listener, long eventMask) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            awtEventsManager.addAWTEventListener(listener, eventMask);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Removes the specified awt event listener.
+     * 
+     * @param listener the AWTEventListener to be removed.
+     */
+    public void removeAWTEventListener(AWTEventListener listener) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            awtEventsManager.removeAWTEventListener(listener);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Gets the array of all AWT event listeners registered with this Toolkit.
+     * 
+     * @return the array of all AWT event listeners registered with this Toolkit.
+     */
+    public AWTEventListener[] getAWTEventListeners() {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            return awtEventsManager.getAWTEventListeners();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Returns the array of the AWT event listeners registered with this Toolkit 
+     * for the event types corresponding to the specified event mask.
+     * 
+     * @param eventMask the bit mask of event type.
+     * 
+     * @return the array of the AWT event listeners registered in this Toolkit 
+     * for the event types corresponding to the specified event mask.
+     */
+    public AWTEventListener[] getAWTEventListeners(long eventMask) {
+        lockAWT();
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkPermission(awtEventsManager.permission);
+            }
+            return awtEventsManager.getAWTEventListeners(eventMask);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    /**
+     * Dispatch awt event.
+     * 
+     * @param event the event
+     */
+    void dispatchAWTEvent(AWTEvent event) {
+        awtEventsManager.dispatchAWTEvent(event);
+    }
+    
+    /**
+     * The Class AWTEventsManager.
+     */
+    final class AWTEventsManager {
+
+        /** The permission. */
+        AWTPermission permission = new AWTPermission("listenToAllAWTEvents"); //$NON-NLS-1$
+
+        /** The listeners. */
+        private final AWTListenerList<AWTEventListenerProxy> listeners = new AWTListenerList<AWTEventListenerProxy>();
+
+        /**
+         * Adds the awt event listener.
+         * 
+         * @param listener the listener
+         * @param eventMask the event mask
+         */
+        void addAWTEventListener(AWTEventListener listener, long eventMask) {
+            if (listener != null) {
+                listeners.addUserListener(new AWTEventListenerProxy(eventMask, listener));
+            }
+        }
+
+        /**
+         * Removes the awt event listener.
+         * 
+         * @param listener the listener
+         */
+        void removeAWTEventListener(AWTEventListener listener) {
+            if (listener != null) {
+                for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                    if (listener == proxy.getListener()) {
+                        listeners.removeUserListener(proxy);
+                        return;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Gets the aWT event listeners.
+         * 
+         * @return the aWT event listeners
+         */
+        AWTEventListener[] getAWTEventListeners() {
+            HashSet<EventListener> listenersSet = new HashSet<EventListener>();
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                listenersSet.add(proxy.getListener());
+            }
+            return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
+        }
+
+        /**
+         * Gets the aWT event listeners.
+         * 
+         * @param eventMask the event mask
+         * 
+         * @return the aWT event listeners
+         */
+        AWTEventListener[] getAWTEventListeners(long eventMask) {
+            HashSet<EventListener> listenersSet = new HashSet<EventListener>();
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                if ((proxy.getEventMask() & eventMask) == eventMask) {
+                    listenersSet.add(proxy.getListener());
+                }
+            }
+            return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
+        }
+
+        /**
+         * Dispatch awt event.
+         * 
+         * @param event the event
+         */
+        void dispatchAWTEvent(AWTEvent event) {
+            AWTEvent.EventDescriptor descriptor = eventTypeLookup.getEventDescriptor(event);
+            if (descriptor == null) {
+                return;
+            }
+            for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
+                if ((proxy.getEventMask() & descriptor.eventMask) != 0) {
+                    proxy.eventDispatched(event);
+                }
+            }
+        }
+    }
+    
+    /**
+     * The Class AutoNumber.
+     */
+    static final class AutoNumber {
+
+        /** The next component. */
+        int nextComponent = 0;
+
+        /** The next canvas. */
+        int nextCanvas = 0;
+
+        /** The next panel. */
+        int nextPanel = 0;
+
+        /** The next window. */
+        int nextWindow = 0;
+
+        /** The next frame. */
+        int nextFrame = 0;
+
+        /** The next dialog. */
+        int nextDialog = 0;
+
+        /** The next button. */
+        int nextButton = 0;
+
+        /** The next menu component. */
+        int nextMenuComponent = 0;
+
+        /** The next label. */
+        int nextLabel = 0;
+
+        /** The next check box. */
+        int nextCheckBox = 0;
+
+        /** The next scrollbar. */
+        int nextScrollbar = 0;
+
+        /** The next scroll pane. */
+        int nextScrollPane = 0;
+
+        /** The next list. */
+        int nextList = 0;
+
+        /** The next choice. */
+        int nextChoice = 0;
+
+        /** The next file dialog. */
+        int nextFileDialog = 0;
+
+        /** The next text area. */
+        int nextTextArea = 0;
+
+        /** The next text field. */
+        int nextTextField = 0;
+    }
+    
+    private class Lock {
+    }
+
+        /** The lock. */
+    private final Object lock = new Lock();
+        
+}
diff --git a/awt/java/awt/ToolkitImpl.java b/awt/java/awt/ToolkitImpl.java
new file mode 100644
index 0000000..5015aef
--- /dev/null
+++ b/awt/java/awt/ToolkitImpl.java
@@ -0,0 +1,255 @@
+/*
+ *  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 java.awt;
+
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.peer.*;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.Hashtable;
+import java.util.Map;
+import org.apache.harmony.awt.gl.image.*;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+
+class ToolkitImpl extends Toolkit {
+	
+    static final Hashtable<Serializable, Image> imageCache = new Hashtable<Serializable, Image>();
+
+    @Override
+    public void sync() {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public int checkImage(Image image, int width, int height, ImageObserver observer) {
+        lockAWT();
+        try {
+            if (width == 0 || height == 0) {
+                return ImageObserver.ALLBITS;
+            }
+            if (!(image instanceof OffscreenImage)) {
+                return ImageObserver.ALLBITS;
+            }
+            OffscreenImage oi = (OffscreenImage) image;
+            return oi.checkImage(observer);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(ImageProducer producer) {
+        lockAWT();
+        try {
+            return new OffscreenImage(producer);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(byte[] imagedata, int imageoffset, int imagelength) {
+        lockAWT();
+        try {
+            return new OffscreenImage(new ByteArrayDecodingImageSource(imagedata, imageoffset,
+                    imagelength));
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(URL url) {
+        lockAWT();
+        try {
+            return new OffscreenImage(new URLDecodingImageSource(url));
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image createImage(String filename) {
+        lockAWT();
+        try {
+            return new OffscreenImage(new FileDecodingImageSource(filename));
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public ColorModel getColorModel() {
+        lockAWT();
+        try {
+            return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()
+                    .getDefaultConfiguration().getColorModel();
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    @Deprecated
+    public FontMetrics getFontMetrics(Font font) {
+        lockAWT();
+        try {
+        	GraphicsFactory gf = getGraphicsFactory();
+            return gf.getFontMetrics(font);
+        } finally {
+            unlockAWT();
+        }
+    }
+    
+    @Override
+    public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
+        lockAWT();
+        try {
+            if (width == 0 || height == 0) {
+                return true;
+            }
+            if (!(image instanceof OffscreenImage)) {
+                return true;
+            }
+            OffscreenImage oi = (OffscreenImage) image;
+            return oi.prepareImage(observer);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public void beep() {
+        lockAWT();
+        try {
+        	// ???AWT: is there nothing to be implemented here?
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    @Deprecated
+    public String[] getFontList() {
+        lockAWT();
+        try {
+        } finally {
+            unlockAWT();
+        }
+        return null;
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    @Deprecated
+    protected FontPeer getFontPeer(String a0, int a1) {
+        lockAWT();
+        try {
+            return null;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Image getImage(String filename) {
+        return getImage(filename, this);
+    }
+
+    static Image getImage(String filename, Toolkit toolkit) {
+        synchronized (imageCache) {
+            Image im = (filename == null ? null : imageCache.get(filename));
+
+            if (im == null) {
+                try {
+                    im = toolkit.createImage(filename);
+                    imageCache.put(filename, im);
+                } catch (Exception e) {
+                }
+            }
+
+            return im;
+        }
+    }
+
+    @Override
+    public Image getImage(URL url) {
+        return getImage(url, this);
+    }
+
+    static Image getImage(URL url, Toolkit toolkit) {
+        synchronized (imageCache) {
+            Image im = imageCache.get(url);
+            if (im == null) {
+                try {
+                    im = toolkit.createImage(url);
+                    imageCache.put(url, im);
+                } catch (Exception e) {
+                }
+            }
+            return im;
+        }
+    }
+
+    @Override
+    public int getScreenResolution() throws HeadlessException {
+        lockAWT();
+        try {
+        	return 62;
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Dimension getScreenSize() {
+        lockAWT();
+        try {
+            DisplayMode dm = GraphicsEnvironment.getLocalGraphicsEnvironment()
+                    .getDefaultScreenDevice().getDisplayMode();
+            return new Dimension(dm.getWidth(), dm.getHeight());
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    public Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
+            InputMethodHighlight highlight) throws HeadlessException {
+        lockAWT();
+        try {
+            return mapInputMethodHighlightImpl(highlight);
+        } finally {
+            unlockAWT();
+        }
+    }
+
+    @Override
+    protected EventQueue getSystemEventQueueImpl() {
+        return getSystemEventQueueCore().getActiveEventQueue();
+    }
+}
diff --git a/awt/java/awt/Transparency.java b/awt/java/awt/Transparency.java
new file mode 100644
index 0000000..9793114
--- /dev/null
+++ b/awt/java/awt/Transparency.java
@@ -0,0 +1,51 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt;
+
+/**
+ * The Transparency interface defines transparency's general modes.
+ */
+public interface Transparency {
+
+    /** The Constant OPAQUE represents completely opaque data,
+     * all pixels have an alpha value of 1.0. 
+     */
+    public static final int OPAQUE = 1;
+
+    /** The Constant BITMASK represents data which can be either 
+     * completely opaque, with an alpha value of 1.0, or completely 
+     * transparent, with an alpha value of 0.0.
+     */
+    public static final int BITMASK = 2;
+
+    /** The Constant TRANSLUCENT represents data which alpha value
+     * can vary between and including 0.0 and 1.0. */
+    public static final int TRANSLUCENT = 3;
+
+    /**
+     * Gets the transparency mode.
+     * 
+     * @return the transparency mode: OPAQUE, BITMASK or TRANSLUCENT.  
+     */
+    public int getTransparency();
+
+}
+
diff --git a/awt/java/awt/color/CMMException.java b/awt/java/awt/color/CMMException.java
new file mode 100644
index 0000000..16fe76e
--- /dev/null
+++ b/awt/java/awt/color/CMMException.java
@@ -0,0 +1,40 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The CMMException is thrown as soon as a native CMM error
+ * occures.
+ */
+public class CMMException extends java.lang.RuntimeException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 5775558044142994965L;
+
+    /**
+     * Instantiates a new CMM exception with detail message.
+     * 
+     * @param s the String - detail message.
+     */
+    public CMMException (String s) {
+        super (s);
+    }
+}
diff --git a/awt/java/awt/color/ColorSpace.java b/awt/java/awt/color/ColorSpace.java
new file mode 100644
index 0000000..f961514
--- /dev/null
+++ b/awt/java/awt/color/ColorSpace.java
@@ -0,0 +1,340 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import java.io.Serializable;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ColorSpace class defines a color space type for a Color and provides methods
+ * for arrays of color component operations.
+ */
+public abstract class ColorSpace implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -409452704308689724L;
+
+    /** The Constant TYPE_XYZ indicates XYZ color space type. */
+    public static final int TYPE_XYZ = 0;
+
+    /** The Constant TYPE_Lab indicates Lab color space type. */
+    public static final int TYPE_Lab = 1;
+
+    /** The Constant TYPE_Luv indicates Luv color space type. */
+    public static final int TYPE_Luv = 2;
+
+    /** The Constant TYPE_YCbCr indicates YCbCr color space type. */
+    public static final int TYPE_YCbCr = 3;
+
+    /** The Constant TYPE_Yxy indicates Yxy color space type. */
+    public static final int TYPE_Yxy = 4;
+
+    /** The Constant TYPE_RGB indicates RGB color space type. */
+    public static final int TYPE_RGB = 5;
+
+    /** The Constant TYPE_GRAY indicates Gray color space type. */
+    public static final int TYPE_GRAY = 6;
+
+    /** The Constant TYPE_HSV indicates HSV color space type. */
+    public static final int TYPE_HSV = 7;
+
+    /** The Constant TYPE_HLS indicates HLS color space type. */
+    public static final int TYPE_HLS = 8;
+
+    /** The Constant TYPE_CMYK indicates CMYK color space type. */
+    public static final int TYPE_CMYK = 9;
+
+    /** The Constant TYPE_CMY indicates CMY color space type. */
+    public static final int TYPE_CMY = 11;
+
+    /** The Constant TYPE_2CLR indicates color spaces with 2 components. */
+    public static final int TYPE_2CLR = 12;
+
+    /** The Constant TYPE_3CLR indicates color spaces with 3 components. */
+    public static final int TYPE_3CLR = 13;
+
+    /** The Constant TYPE_4CLR indicates color spaces with 4 components. */
+    public static final int TYPE_4CLR = 14;
+
+    /** The Constant TYPE_5CLR indicates color spaces with 5 components. */
+    public static final int TYPE_5CLR = 15;
+
+    /** The Constant TYPE_6CLR indicates color spaces with 6 components. */
+    public static final int TYPE_6CLR = 16;
+
+    /** The Constant TYPE_7CLR indicates color spaces with 7 components. */
+    public static final int TYPE_7CLR = 17;
+
+    /** The Constant TYPE_8CLR indicates color spaces with 8 components. */
+    public static final int TYPE_8CLR = 18;
+
+    /** The Constant TYPE_9CLR indicates color spaces with 9 components. */
+    public static final int TYPE_9CLR = 19;
+
+    /** The Constant TYPE_ACLR indicates color spaces with 10 components. */
+    public static final int TYPE_ACLR = 20;
+
+    /** The Constant TYPE_BCLR indicates color spaces with 11 components. */
+    public static final int TYPE_BCLR = 21;
+
+    /** The Constant TYPE_CCLR indicates color spaces with 12 components. */
+    public static final int TYPE_CCLR = 22;
+
+    /** The Constant TYPE_DCLR indicates color spaces with 13 components. */
+    public static final int TYPE_DCLR = 23;
+
+    /** The Constant TYPE_ECLR indicates color spaces with 14 components. */
+    public static final int TYPE_ECLR = 24;
+
+    /** The Constant TYPE_FCLR indicates color spaces with 15 components. */
+    public static final int TYPE_FCLR = 25;
+
+    /** The Constant CS_sRGB indicates standard RGB color space.*/
+    public static final int CS_sRGB = 1000;
+
+    /** The Constant CS_LINEAR_RGB indicates linear RGB color space. */
+    public static final int CS_LINEAR_RGB = 1004;
+
+    /** The Constant CS_CIEXYZ indicates CIEXYZ conversion color space. */
+    public static final int CS_CIEXYZ = 1001;
+
+    /** The Constant CS_PYCC indicates Photo YCC conversion color space. */
+    public static final int CS_PYCC = 1002;
+
+    /** The Constant CS_GRAY indicates linear gray scale color space. */
+    public static final int CS_GRAY = 1003;
+
+    /** The cs_ gray. */
+    private static ColorSpace cs_Gray = null;
+    
+    /** The cs_ pycc. */
+    private static ColorSpace cs_PYCC = null;
+    
+    /** The cs_ ciexyz. */
+    private static ColorSpace cs_CIEXYZ = null;
+    
+    /** The cs_ lrgb. */
+    private static ColorSpace cs_LRGB = null;
+    
+    /** The cs_s rgb. */
+    private static ColorSpace cs_sRGB = null;
+
+    /** The type. */
+    private int type;
+    
+    /** The num components. */
+    private int numComponents;
+
+    /**
+     * Instantiates a ColorSpace with the specified
+     * ColorSpace type and number of components.
+     * 
+     * @param type the type of color space.
+     * @param numcomponents the number of components.
+     */
+    protected ColorSpace(int type, int numcomponents) {
+        this.numComponents = numcomponents;
+        this.type = type;
+    }
+
+    /**
+     * Gets the name of the component for the specified component index.
+     * 
+     * @param idx the index of the component.
+     * 
+     * @return the name of the component.
+     */
+    public String getName(int idx) {
+        if (idx < 0 || idx > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", idx)); //$NON-NLS-1$
+        }
+
+      return "Unnamed color component #" + idx; //$NON-NLS-1$
+    }
+
+    /**
+     * Perform transformation a color from this ColorSpace 
+     * into the RGB color space.
+     * 
+     * @param colorvalue the color value in this ColorSpace.
+     * 
+     * @return the float array with color components in the 
+     * RGB color space.
+     */
+    public abstract float[] toRGB(float[] colorvalue);
+
+    /**
+     * Perform transformation a color from this ColorSpace 
+     * into the CS_CIEXYZ color space.
+     * 
+     * @param colorvalue the color value in this ColorSpace.
+     * 
+     * @return the float array with color components in the 
+     * CS_CIEXYZ color space. 
+     */
+    public abstract float[] toCIEXYZ(float[] colorvalue);
+
+    /**
+     * Performs color transformation from the RGB color space 
+     * into this ColorSpace.
+     * 
+     * @param rgbvalue a float array in the RGB color space.
+     * 
+     * @return the float[] an array of transformed color
+     * components. 
+     */
+    public abstract float[] fromRGB(float[] rgbvalue);
+
+    /**
+     * Performs color transformation from the CS_CIEXYZ color space 
+     * into this ColorSpace.
+     * 
+     * @param colorvalue a float array in the CS_CIEXYZ color space.
+     * 
+     * @return the float[] an array of transformed color
+     * components. 
+     */
+    public abstract float[] fromCIEXYZ(float[] colorvalue);
+
+    /**
+     * Gets the minimum normalized color component value for 
+     * the specified component.
+     * 
+     * @param component the component.
+     * 
+     * @return the miniimum normalized value of the component.
+     */
+    public float getMinValue(int component) {
+        if (component < 0 || component > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", component)); //$NON-NLS-1$
+        }
+        return 0;
+    }
+
+    /**
+     * Gets the maximum normalized color component value for 
+     * the specified component.
+     * 
+     * @param component the component.
+     * 
+     * @return the maximum normalized value of the component.
+     */
+    public float getMaxValue(int component) {
+        if (component < 0 || component > numComponents - 1) {
+            // awt.16A=Invalid component index: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.16A", component)); //$NON-NLS-1$
+        }
+        return 1;
+    }
+
+    /**
+     * Checks if this ColorSpace has CS_sRGB type or not.
+     * 
+     * @return true, if this ColorSpace has CS_sRGB type, 
+     * false otherwise.
+     */
+    public boolean isCS_sRGB() {
+        // If our color space is sRGB, then cs_sRGB
+        // is already initialized
+        return (this == cs_sRGB);
+    }
+
+    /**
+     * Gets the type of the ColorSpace.
+     * 
+     * @return the type of the ColorSpace.
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Gets the number of components for this ColorSpace.
+     * 
+     * @return the number of components.
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+
+    /**
+     * Gets the single instance of ColorSpace with the specified
+     * ColorSpace: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ, CS_GRAY, 
+     * or CS_PYCC.
+     * 
+     * @param colorspace the identifier of the specified Colorspace.
+     * 
+     * @return the single instance of the desired ColorSpace.
+     */
+    public static ColorSpace getInstance(int colorspace) {
+        switch (colorspace) {
+            case CS_sRGB:
+                if (cs_sRGB == null) {
+                    cs_sRGB = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_sRGB));
+                    LUTColorConverter.sRGB_CS = cs_sRGB;
+                            //ICC_Profile.getInstance (CS_sRGB));
+                }
+                return cs_sRGB;
+            case CS_CIEXYZ:
+                if (cs_CIEXYZ == null) {
+                    cs_CIEXYZ = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_CIEXYZ));
+                            //ICC_Profile.getInstance (CS_CIEXYZ));
+                }
+                return cs_CIEXYZ;
+            case CS_GRAY:
+                if (cs_Gray == null) {
+                    cs_Gray = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_GRAY));
+                    LUTColorConverter.LINEAR_GRAY_CS = cs_Gray;
+                            //ICC_Profile.getInstance (CS_GRAY));
+                }
+                return cs_Gray;
+            case CS_PYCC:
+                if (cs_PYCC == null) {
+                    cs_PYCC = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_PYCC));
+                            //ICC_Profile.getInstance (CS_PYCC));
+                }
+                return cs_PYCC;
+            case CS_LINEAR_RGB:
+                if (cs_LRGB == null) {
+                    cs_LRGB = new ICC_ColorSpace(
+                            new ICC_ProfileStub(CS_LINEAR_RGB));
+                    LUTColorConverter.LINEAR_GRAY_CS = cs_Gray;
+                            //ICC_Profile.getInstance (CS_LINEAR_RGB));
+                }
+                return cs_LRGB;
+            default:
+        }
+
+        // Unknown argument passed
+        // awt.16B=Not a predefined colorspace
+        throw new IllegalArgumentException(Messages.getString("Not a predefined colorspace")); //$NON-NLS-1$
+    }
+
+}
\ No newline at end of file
diff --git a/awt/java/awt/color/ICC_ColorSpace.java b/awt/java/awt/color/ICC_ColorSpace.java
new file mode 100644
index 0000000..5ece2ef
--- /dev/null
+++ b/awt/java/awt/color/ICC_ColorSpace.java
@@ -0,0 +1,379 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import org.apache.harmony.awt.gl.color.ColorConverter;
+import org.apache.harmony.awt.gl.color.ColorScaler;
+import org.apache.harmony.awt.gl.color.ICC_Transform;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+import java.io.*;
+
+/**
+ * ICC_ColorSpace class implements ColorSpace abstract class and 
+ * represents device independent and device dependent color spaces.
+ * This color space is based on the International Color Consortium 
+ * Specification (ICC) File Format for Color Profiles: 
+ * <a href="http://www.color.org">http://www.color.org</a>
+ */
+public class ICC_ColorSpace extends ColorSpace {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 3455889114070431483L;
+
+    // Need to keep compatibility with serialized form
+    /** The Constant serialPersistentFields. */
+    private static final ObjectStreamField[]
+      serialPersistentFields = {
+        new ObjectStreamField("thisProfile", ICC_Profile.class), //$NON-NLS-1$
+        new ObjectStreamField("minVal", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("maxVal", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("diffMinMax", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("invDiffMinMax", float[].class), //$NON-NLS-1$
+        new ObjectStreamField("needScaleInit", Boolean.TYPE) //$NON-NLS-1$
+    };
+
+
+   /**
+    * According to ICC specification (from http://www.color.org)
+    * "For the CIEXYZ encoding, each component (X, Y, and Z)
+    * is encoded as a u1Fixed15Number".
+    * This means that max value for this encoding is 1 + (32767/32768)
+    */
+    private static final float MAX_XYZ = 1f + (32767f/32768f);
+    
+    /** The Constant MAX_SHORT. */
+    private static final float MAX_SHORT = 65535f;
+    
+    /** The Constant INV_MAX_SHORT. */
+    private static final float INV_MAX_SHORT = 1f/MAX_SHORT;
+    
+    /** The Constant SHORT2XYZ_FACTOR. */
+    private static final float SHORT2XYZ_FACTOR = MAX_XYZ/MAX_SHORT;
+    
+    /** The Constant XYZ2SHORT_FACTOR. */
+    private static final float XYZ2SHORT_FACTOR = MAX_SHORT/MAX_XYZ;
+
+    /** The profile. */
+    private ICC_Profile profile = null;
+    
+    /** The min values. */
+    private float minValues[] = null;
+    
+    /** The max values. */
+    private float maxValues[] = null;
+
+    // cache transforms here - performance gain
+    /** The to rgb transform. */
+    private ICC_Transform toRGBTransform = null;
+    
+    /** The from rgb transform. */
+    private ICC_Transform fromRGBTransform = null;
+    
+    /** The to xyz transform. */
+    private ICC_Transform toXYZTransform = null;
+    
+    /** The from xyz transform. */
+    private ICC_Transform fromXYZTransform = null;
+
+    /** The converter. */
+    private final ColorConverter converter = new ColorConverter();
+    
+    /** The scaler. */
+    private final ColorScaler scaler = new ColorScaler();
+    
+    /** The scaling data loaded. */
+    private boolean scalingDataLoaded = false;
+
+    /** The resolved deserialized inst. */
+    private ICC_ColorSpace resolvedDeserializedInst;
+
+    /**
+     * Instantiates a new ICC color space from an ICC_Profile object.
+     * 
+     * @param pf the ICC_Profile object.
+     */
+    public ICC_ColorSpace(ICC_Profile pf) {
+        super(pf.getColorSpaceType(), pf.getNumComponents());
+
+        int pfClass = pf.getProfileClass();
+
+        switch (pfClass) {
+            case ICC_Profile.CLASS_COLORSPACECONVERSION:
+            case ICC_Profile.CLASS_DISPLAY:
+            case ICC_Profile.CLASS_OUTPUT:
+            case ICC_Profile.CLASS_INPUT:
+                break; // OK, it is color conversion profile
+            default:
+                // awt.168=Invalid profile class.
+                throw new IllegalArgumentException(Messages.getString("awt.168")); //$NON-NLS-1$
+        }
+
+        profile = pf;
+        fillMinMaxValues();
+    }
+
+    /**
+     * Returns the ICC_Profile for this ICC_ColorSpace.
+     * 
+     * @return the ICC_Profile for this ICC_ColorSpace.
+     */
+    public ICC_Profile getProfile() {
+        if (profile instanceof ICC_ProfileStub) {
+            profile = ((ICC_ProfileStub) profile).loadProfile();
+        }
+
+        return profile;
+    }
+
+    @Override
+    public float[] toRGB(float[] colorvalue) {
+        if (toRGBTransform == null) {
+            ICC_Profile sRGBProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB)).getProfile();
+            ICC_Profile[] profiles = {getProfile(), sRGBProfile};
+            toRGBTransform = new ICC_Transform(profiles);
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        short[] data = new short[getNumComponents()];
+
+        scaler.scale(colorvalue, data, 0);
+
+        short[] converted =
+            converter.translateColor(toRGBTransform, data, null);
+
+        // unscale to sRGB
+        float[] res = new float[3];
+
+        res[0] = ((converted[0] & 0xFFFF)) * INV_MAX_SHORT;
+        res[1] = ((converted[1] & 0xFFFF)) * INV_MAX_SHORT;
+        res[2] = ((converted[2] & 0xFFFF)) * INV_MAX_SHORT;
+
+        return res;
+    }
+
+    @Override
+    public float[] toCIEXYZ(float[] colorvalue) {
+        if (toXYZTransform == null) {
+            ICC_Profile xyzProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ)).getProfile();
+            ICC_Profile[] profiles = {getProfile(), xyzProfile};
+            try {
+                int[] intents = {
+                        ICC_Profile.icRelativeColorimetric,
+                        ICC_Profile.icPerceptual};
+                toXYZTransform = new ICC_Transform(profiles, intents);
+            } catch (CMMException e) { // No such tag, use what we can
+                toXYZTransform = new ICC_Transform(profiles);
+            }
+
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        short[] data = new short[getNumComponents()];
+
+        scaler.scale(colorvalue, data, 0);
+
+        short[] converted =
+            converter.translateColor(toXYZTransform, data, null);
+
+        // unscale to XYZ
+        float[] res = new float[3];
+
+        res[0] = ((converted[0] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+        res[1] = ((converted[1] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+        res[2] = ((converted[2] & 0xFFFF)) * SHORT2XYZ_FACTOR;
+
+        return res;
+    }
+
+    @Override
+    public float[] fromRGB(float[] rgbvalue) {
+        if (fromRGBTransform == null) {
+            ICC_Profile sRGBProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB)).getProfile();
+            ICC_Profile[] profiles = {sRGBProfile, getProfile()};
+            fromRGBTransform = new ICC_Transform(profiles);
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+        }
+
+        // scale rgb value to short
+        short[] scaledRGBValue = new short[3];
+        scaledRGBValue[0] = (short)(rgbvalue[0] * MAX_SHORT + 0.5f);
+        scaledRGBValue[1] = (short)(rgbvalue[1] * MAX_SHORT + 0.5f);
+        scaledRGBValue[2] = (short)(rgbvalue[2] * MAX_SHORT + 0.5f);
+
+        short[] converted =
+            converter.translateColor(fromRGBTransform, scaledRGBValue, null);
+
+        float[] res = new float[getNumComponents()];
+
+        scaler.unscale(res, converted, 0);
+
+        return res;
+    }
+
+    @Override
+    public float[] fromCIEXYZ(float[] xyzvalue) {
+        if (fromXYZTransform == null) {
+            ICC_Profile xyzProfile =
+                ((ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ)).getProfile();
+            ICC_Profile[] profiles = {xyzProfile, getProfile()};
+            try {
+                int[] intents = {
+                        ICC_Profile.icPerceptual,
+                        ICC_Profile.icRelativeColorimetric};
+                fromXYZTransform = new ICC_Transform(profiles, intents);
+            } catch (CMMException e) { // No such tag, use what we can
+                fromXYZTransform = new ICC_Transform(profiles);
+            }
+
+            if (!scalingDataLoaded) {
+                scaler.loadScalingData(this);
+                scalingDataLoaded = true;
+            }
+
+        }
+
+        // scale xyz value to short
+        short[] scaledXYZValue = new short[3];
+        scaledXYZValue[0] = (short)(xyzvalue[0] * XYZ2SHORT_FACTOR + 0.5f);
+        scaledXYZValue[1] = (short)(xyzvalue[1] * XYZ2SHORT_FACTOR + 0.5f);
+        scaledXYZValue[2] = (short)(xyzvalue[2] * XYZ2SHORT_FACTOR + 0.5f);
+
+        short[] converted =
+            converter.translateColor(fromXYZTransform, scaledXYZValue, null);
+
+        float[] res = new float[getNumComponents()];
+
+        scaler.unscale(res, converted, 0);
+
+        return res;
+    }
+
+    @Override
+    public float getMinValue(int component) {
+        if ((component < 0) || (component > this.getNumComponents() - 1)) {
+            // awt.169=Component index out of range
+            throw new IllegalArgumentException(Messages.getString("awt.169")); //$NON-NLS-1$
+        }
+
+        return minValues[component];
+    }
+
+    @Override
+    public float getMaxValue(int component) {
+        if ((component < 0) || (component > this.getNumComponents() - 1)) {
+            // awt.169=Component index out of range
+            throw new IllegalArgumentException(Messages.getString("awt.169")); //$NON-NLS-1$
+        }
+
+        return maxValues[component];
+    }
+
+    /**
+     * Fill min max values.
+     */
+    private void fillMinMaxValues() {
+        int n = getNumComponents();
+        maxValues = new float[n];
+        minValues = new float[n];
+        switch (getType()) {
+            case ColorSpace.TYPE_XYZ:
+                minValues[0] = 0;
+                minValues[1] = 0;
+                minValues[2] = 0;
+                maxValues[0] = MAX_XYZ;
+                maxValues[1] = MAX_XYZ;
+                maxValues[2] = MAX_XYZ;
+                break;
+            case ColorSpace.TYPE_Lab:
+                minValues[0] = 0;
+                minValues[1] = -128;
+                minValues[2] = -128;
+                maxValues[0] = 100;
+                maxValues[1] = 127;
+                maxValues[2] = 127;
+                break;
+            default:
+                for(int i=0; i<n; i++) {
+                    minValues[i] = 0;
+                    maxValues[i] = 1;
+                }
+        }
+    }
+
+    /**
+     * Write object.
+     * 
+     * @param out the out
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        ObjectOutputStream.PutField fields = out.putFields();
+
+        fields.put("thisProfile", profile); //$NON-NLS-1$
+        fields.put("minVal", null); //$NON-NLS-1$
+        fields.put("maxVal", null); //$NON-NLS-1$
+        fields.put("diffMinMax", null); //$NON-NLS-1$
+        fields.put("invDiffMinMax", null); //$NON-NLS-1$
+        fields.put("needScaleInit", true); //$NON-NLS-1$
+
+        out.writeFields();
+    }
+
+    /**
+     * Read object.
+     * 
+     * @param in the in
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException the class not found exception
+     */
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+        ObjectInputStream.GetField fields = in.readFields();
+        resolvedDeserializedInst =
+                new ICC_ColorSpace((ICC_Profile) fields.get("thisProfile", null)); //$NON-NLS-1$
+    }
+
+    /**
+     * Read resolve.
+     * 
+     * @return the object
+     * 
+     * @throws ObjectStreamException the object stream exception
+     */
+    Object readResolve() throws ObjectStreamException {
+        return resolvedDeserializedInst;
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_Profile.java b/awt/java/awt/color/ICC_Profile.java
new file mode 100644
index 0000000..ad704e0
--- /dev/null
+++ b/awt/java/awt/color/ICC_Profile.java
@@ -0,0 +1,1231 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.awt.gl.color.ICC_ProfileHelper;
+import org.apache.harmony.awt.gl.color.NativeCMM;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ICC_Profile class represents a color profile data for color spaces 
+ * based on the International Color Consortium Specification ICC.1:2001-12, 
+ * File Format for Color Profiles.
+ */
+public class ICC_Profile implements Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -3938515861990936766L;
+
+    // NOTE: Constant field values are noted in 1.5 specification.
+
+    /**
+     * The Constant CLASS_INPUT indicates that profile class is input. 
+     */
+    public static final int CLASS_INPUT = 0;
+
+    /** 
+     * The Constant CLASS_DISPLAY indicates that profile class is display. 
+     */
+    public static final int CLASS_DISPLAY = 1;
+
+    /** 
+     * The Constant CLASS_OUTPUT indicates that profile class is output. 
+     */
+    public static final int CLASS_OUTPUT = 2;
+
+    /** 
+     * The Constant CLASS_DEVICELINK indicates that profile class 
+     * is device link. 
+     */
+    public static final int CLASS_DEVICELINK = 3;
+
+    /** 
+     * The Constant CLASS_COLORSPACECONVERSION indicates that profile class 
+     * is color space conversion.
+     */
+    public static final int CLASS_COLORSPACECONVERSION = 4;
+
+    /** The Constant CLASS_ABSTRACT indicates that profile class is abstract. */
+    public static final int CLASS_ABSTRACT = 5;
+
+    /** 
+     * The Constant CLASS_NAMEDCOLOR indicates that profile class 
+     * is named color. 
+     */
+    public static final int CLASS_NAMEDCOLOR = 6;
+
+    /** The Constant icSigXYZData - ICC Profile Color Space Type Signature. */
+    public static final int icSigXYZData = 1482250784;
+
+    /** The Constant icSigLabData - ICC Profile Color Space Type Signature. */
+    public static final int icSigLabData = 1281450528;
+
+    /** The Constant icSigLuvData - ICC Profile Color Space Type Signature. */
+    public static final int icSigLuvData = 1282766368;
+
+    /** The Constant icSigYCbCrData - ICC Profile Color Space Type Signature. */
+    public static final int icSigYCbCrData = 1497588338;
+
+    /** The Constant icSigYxyData - ICC Profile Color Space Type Signature. */
+    public static final int icSigYxyData = 1501067552;
+
+    /** The Constant icSigRgbData - ICC Profile Color Space Type Signature. */
+    public static final int icSigRgbData = 1380401696;
+
+    /** The Constant icSigGrayData - ICC Profile Color Space Type Signature. */
+    public static final int icSigGrayData = 1196573017;
+
+    /** The Constant icSigHsvData - ICC Profile Color Space Type Signature. */
+    public static final int icSigHsvData = 1213421088;
+
+    /** The Constant icSigHlsData - ICC Profile Color Space Type Signature. */
+    public static final int icSigHlsData = 1212961568;
+
+    /** The Constant icSigCmykData - ICC Profile Color Space Type Signature. */
+    public static final int icSigCmykData = 1129142603;
+
+    /** The Constant icSigCmyData - ICC Profile Color Space Type Signature. */
+    public static final int icSigCmyData = 1129142560;
+
+    /** The Constant icSigSpace2CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace2CLR = 843271250;
+
+    /** The Constant icSigSpace3CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace3CLR = 860048466;
+
+    /** The Constant icSigSpace4CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace4CLR = 876825682;
+
+    /** The Constant icSigSpace5CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace5CLR = 893602898;
+
+    /** The Constant icSigSpace6CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace6CLR = 910380114;
+
+    /** The Constant icSigSpace7CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace7CLR = 927157330;
+
+    /** The Constant icSigSpace8CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace8CLR = 943934546;
+
+    /** The Constant icSigSpace9CLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpace9CLR = 960711762;
+
+    /** The Constant icSigSpaceACLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceACLR = 1094929490;
+
+    /** The Constant icSigSpaceBCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceBCLR = 1111706706;
+
+    /** The Constant icSigSpaceCCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceCCLR = 1128483922;
+
+    /** The Constant icSigSpaceDCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceDCLR = 1145261138;
+
+    /** The Constant icSigSpaceECLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceECLR = 1162038354;
+
+    /** The Constant icSigSpaceFCLR - ICC Profile Color Space Type Signature. */
+    public static final int icSigSpaceFCLR = 1178815570;
+
+    /** The Constant icSigInputClass - ICC Profile Class Signature. */
+    public static final int icSigInputClass = 1935896178;
+
+    /** The Constant icSigDisplayClass - ICC Profile Class Signature. */
+    public static final int icSigDisplayClass = 1835955314;
+
+    /** The Constant icSigOutputClass - ICC Profile Class Signature. */
+    public static final int icSigOutputClass = 1886549106;
+
+    /** The Constant icSigLinkClass - ICC Profile Class Signature. */
+    public static final int icSigLinkClass = 1818848875;
+
+    /** The Constant icSigAbstractClass - ICC Profile Class Signature. */
+    public static final int icSigAbstractClass = 1633842036;
+
+    /** The Constant icSigColorantOrderTag - ICC Profile Tag Signature. */
+    public static final int icSigColorantOrderTag = 1668051567;
+
+    /** The Constant icSigColorantTableTag - ICC Profile Tag Signature. */
+    public static final int icSigColorantTableTag = 1668051572;
+
+    /** The Constant icSigColorSpaceClass - ICC Profile Tag Signature. */
+    public static final int icSigColorSpaceClass = 1936744803;
+
+    /** The Constant icSigNamedColorClass - ICC Profile Tag Signature. */
+    public static final int icSigNamedColorClass = 1852662636;
+
+    /** The Constant icPerceptual - ICC Profile Rendering Intent. */
+    public static final int icPerceptual = 0;
+
+    /** The Constant icRelativeColorimetric - ICC Profile Rendering Intent. */
+    public static final int icRelativeColorimetric = 1;
+
+    /** The Constant icSaturation - ICC Profile Rendering Intent. */
+    public static final int icSaturation = 2;
+
+    /** The Constant icAbsoluteColorimetric - ICC Profile Rendering Intent. */
+    public static final int icAbsoluteColorimetric = 3;
+
+    /** The Constant icSigHead - ICC Profile Tag Signature. */
+    public static final int icSigHead = 1751474532;
+
+    /** The Constant icSigAToB0Tag - ICC Profile Tag Signature. */
+    public static final int icSigAToB0Tag = 1093812784;
+
+    /** The Constant icSigAToB1Tag - ICC Profile Tag Signature. */
+    public static final int icSigAToB1Tag = 1093812785;
+
+    /** The Constant icSigAToB2Tag - ICC Profile Tag Signature. */
+    public static final int icSigAToB2Tag = 1093812786;
+
+    /** The Constant icSigBlueColorantTag - ICC Profile Tag Signature. */
+    public static final int icSigBlueColorantTag = 1649957210;
+
+    /** The Constant icSigBlueMatrixColumnTag - ICC Profile Tag Signature. */
+    public static final int icSigBlueMatrixColumnTag = 1649957210;
+
+    /** The Constant icSigBlueTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigBlueTRCTag = 1649693251;
+
+    /** The Constant icSigBToA0Tag - ICC Profile Tag Signature. */
+    public static final int icSigBToA0Tag = 1110589744;
+
+    /** The Constant icSigBToA1Tag - ICC Profile Tag Signature. */
+    public static final int icSigBToA1Tag = 1110589745;
+
+    /** The Constant icSigBToA2Tag - ICC Profile Tag Signature. */
+    public static final int icSigBToA2Tag = 1110589746;
+
+    /** The Constant icSigCalibrationDateTimeTag - ICC Profile Tag Signature. */
+    public static final int icSigCalibrationDateTimeTag = 1667329140;
+
+    /** The Constant icSigCharTargetTag - ICC Profile Tag Signature. */
+    public static final int icSigCharTargetTag = 1952543335;
+
+    /** The Constant icSigCopyrightTag - ICC Profile Tag Signature. */
+    public static final int icSigCopyrightTag = 1668313716;
+
+    /** The Constant icSigCrdInfoTag - ICC Profile Tag Signature. */
+    public static final int icSigCrdInfoTag = 1668441193;
+
+    /** The Constant icSigDeviceMfgDescTag - ICC Profile Tag Signature. */
+    public static final int icSigDeviceMfgDescTag = 1684893284;
+
+    /** The Constant icSigDeviceModelDescTag - ICC Profile Tag Signature. */
+    public static final int icSigDeviceModelDescTag = 1684890724;
+
+    /** The Constant icSigDeviceSettingsTag - ICC Profile Tag Signature. */
+    public static final int icSigDeviceSettingsTag = 1684371059;
+
+    /** The Constant icSigGamutTag - ICC Profile Tag Signature. */
+    public static final int icSigGamutTag = 1734438260;
+
+    /** The Constant icSigGrayTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigGrayTRCTag = 1800688195;
+
+    /** The Constant icSigGreenColorantTag - ICC Profile Tag Signature. */
+    public static final int icSigGreenColorantTag = 1733843290;
+
+    /** The Constant icSigGreenMatrixColumnTag - ICC Profile Tag Signature. */
+    public static final int icSigGreenMatrixColumnTag = 1733843290;
+
+    /** The Constant icSigGreenTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigGreenTRCTag = 1733579331;
+
+    /** The Constant icSigLuminanceTag - ICC Profile Tag Signature. */
+    public static final int icSigLuminanceTag = 1819635049;
+
+    /** The Constant icSigMeasurementTag - ICC Profile Tag Signature. */
+    public static final int icSigMeasurementTag = 1835360627;
+
+    /** The Constant icSigMediaBlackPointTag - ICC Profile Tag Signature. */
+    public static final int icSigMediaBlackPointTag = 1651208308;
+
+    /** The Constant icSigMediaWhitePointTag - ICC Profile Tag Signature. */
+    public static final int icSigMediaWhitePointTag = 2004119668;
+
+    /** The Constant icSigNamedColor2Tag - ICC Profile Tag Signature. */
+    public static final int icSigNamedColor2Tag = 1852009522;
+
+    /** The Constant icSigOutputResponseTag - ICC Profile Tag Signature. */
+    public static final int icSigOutputResponseTag = 1919251312;
+
+    /** The Constant icSigPreview0Tag - ICC Profile Tag Signature. */
+    public static final int icSigPreview0Tag = 1886545200;
+
+    /** The Constant icSigPreview1Tag - ICC Profile Tag Signature. */
+    public static final int icSigPreview1Tag = 1886545201;
+
+    /** The Constant icSigPreview2Tag - ICC Profile Tag Signature. */
+    public static final int icSigPreview2Tag = 1886545202;
+
+    /** The Constant icSigProfileDescriptionTag - ICC Profile Tag Signature. */
+    public static final int icSigProfileDescriptionTag = 1684370275;
+
+    /** The Constant icSigProfileSequenceDescTag - ICC Profile Tag Signature. */
+    public static final int icSigProfileSequenceDescTag = 1886610801;
+
+    /** The Constant icSigPs2CRD0Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD0Tag = 1886610480;
+
+    /** The Constant icSigPs2CRD1Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD1Tag = 1886610481;
+
+    /** The Constant icSigPs2CRD2Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD2Tag = 1886610482;
+
+    /** The Constant icSigPs2CRD3Tag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CRD3Tag = 1886610483;
+
+    /** The Constant icSigPs2CSATag - ICC Profile Tag Signature. */
+    public static final int icSigPs2CSATag = 1886597747;
+
+    /** The Constant icSigPs2RenderingIntentTag - ICC Profile Tag Signature. */
+    public static final int icSigPs2RenderingIntentTag = 1886597737;
+
+    /** The Constant icSigRedColorantTag - ICC Profile Tag Signature. */
+    public static final int icSigRedColorantTag = 1918392666;
+
+    /** The Constant icSigRedMatrixColumnTag - ICC Profile Tag Signature. */
+    public static final int icSigRedMatrixColumnTag = 1918392666;
+
+    /** The Constant icSigRedTRCTag - ICC Profile Tag Signature. */
+    public static final int icSigRedTRCTag = 1918128707;
+
+    /** The Constant icSigScreeningDescTag - ICC Profile Tag Signature. */
+    public static final int icSigScreeningDescTag = 1935897188;
+
+    /** The Constant icSigScreeningTag - ICC Profile Tag Signature. */
+    public static final int icSigScreeningTag = 1935897198;
+
+    /** The Constant icSigTechnologyTag - ICC Profile Tag Signature. */
+    public static final int icSigTechnologyTag = 1952801640;
+
+    /** The Constant icSigUcrBgTag - ICC Profile Tag Signature. */
+    public static final int icSigUcrBgTag = 1650877472;
+
+    /** The Constant icSigViewingCondDescTag - ICC Profile Tag Signature. */
+    public static final int icSigViewingCondDescTag = 1987405156;
+
+    /** The Constant icSigViewingConditionsTag - ICC Profile Tag Signature. */
+    public static final int icSigViewingConditionsTag = 1986618743;
+
+    /** The Constant icSigChromaticAdaptationTag - ICC Profile Tag Signature. */
+    public static final int icSigChromaticAdaptationTag = 1667785060;
+
+    /** The Constant icSigChromaticityTag - ICC Profile Tag Signature. */
+    public static final int icSigChromaticityTag = 1667789421;
+
+    /** The Constant icHdrSize - ICC Profile Header Location. */
+    public static final int icHdrSize = 0;
+
+    /** The Constant icHdrCmmId - ICC Profile Header Location. */
+    public static final int icHdrCmmId = 4;
+
+    /** The Constant icHdrVersion - ICC Profile Header Location. */
+    public static final int icHdrVersion = 8;
+
+    /** The Constant icHdrDeviceClass - ICC Profile Header Location. */
+    public static final int icHdrDeviceClass = 12;
+
+    /** The Constant icHdrColorSpace - ICC Profile Header Location. */
+    public static final int icHdrColorSpace = 16;
+
+    /** The Constant icHdrPcs - ICC Profile Header Location. */
+    public static final int icHdrPcs = 20;
+
+    /** The Constant icHdrDate - ICC Profile Header Location. */
+    public static final int icHdrDate = 24;
+
+    /** The Constant icHdrMagic - ICC Profile Header Location. */
+    public static final int icHdrMagic = 36;
+
+    /** The Constant icHdrPlatform - ICC Profile Header Location. */
+    public static final int icHdrPlatform = 40;
+
+    /** The Constant icHdrProfileID - ICC Profile Header Location. */
+    public static final int icHdrProfileID = 84;
+
+    /** The Constant icHdrFlags - ICC Profile Header Location. */
+    public static final int icHdrFlags = 44;
+
+    /** The Constant icHdrManufacturer - ICC Profile Header Location. */
+    public static final int icHdrManufacturer = 48;
+
+    /** The Constant icHdrModel - ICC Profile Header Location. */
+    public static final int icHdrModel = 52;
+
+    /** The Constant icHdrAttributes - ICC Profile Header Location. */
+    public static final int icHdrAttributes = 56;
+
+    /** The Constant icHdrRenderingIntent - ICC Profile Header Location. */
+    public static final int icHdrRenderingIntent = 64;
+
+    /** The Constant icHdrIlluminant - ICC Profile Header Location. */
+    public static final int icHdrIlluminant = 68;
+
+    /** The Constant icHdrCreator - ICC Profile Header Location. */
+    public static final int icHdrCreator = 80;
+
+    /** The Constant icICCAbsoluteColorimetric - ICC Profile Rendering Intent. */
+    public static final int icICCAbsoluteColorimetric = 3;
+
+    /** The Constant icMediaRelativeColorimetric - ICC Profile Rendering Intent. */
+    public static final int icMediaRelativeColorimetric = 1;
+
+    /** The Constant icTagType - ICC Profile Constant. */
+    public static final int icTagType = 0;
+
+    /** The Constant icTagReserved - ICC Profile Constant. */
+    public static final int icTagReserved = 4;
+
+    /** The Constant icCurveCount - ICC Profile Constant. */
+    public static final int icCurveCount = 8;
+
+    /** The Constant icCurveData - ICC Profile Constant. */
+    public static final int icCurveData = 12;
+
+    /** The Constant icXYZNumberX - ICC Profile Constant. */
+    public static final int icXYZNumberX = 8;
+
+    /** Size of a profile header. */
+    private static final int headerSize = 128;
+
+    /** header magic number. */
+    private static final int headerMagicNumber = 0x61637370;
+
+    // Cache of predefined profiles
+    /** The s rgb profile. */
+    private static ICC_Profile sRGBProfile;
+    
+    /** The xyz profile. */
+    private static ICC_Profile xyzProfile;
+    
+    /** The gray profile. */
+    private static ICC_Profile grayProfile;
+    
+    /** The pycc profile. */
+    private static ICC_Profile pyccProfile;
+    
+    /** The linear rgb profile. */
+    private static ICC_Profile linearRGBProfile;
+
+    /** Handle to the current profile. */
+    private transient long profileHandle = 0;
+
+    /** If handle is used by another class this object is not responsible for closing profile. */
+    private transient boolean handleStolen = false;
+
+    /** Cached header data. */
+    private transient byte[] headerData = null;
+
+    /** Serialization support. */
+    private transient ICC_Profile openedProfileObject;
+
+    /**
+     * Instantiates a new iC c_ profile.
+     * 
+     * @param data the data
+     */
+    private ICC_Profile(byte[] data) {
+        profileHandle = NativeCMM.cmmOpenProfile(data);
+        NativeCMM.addHandle(this, profileHandle);
+    }
+
+    /**
+     * Used to instantiate dummy ICC_ProfileStub objects.
+     */
+    ICC_Profile() {
+    }
+
+    /**
+     * Used to instantiate subclasses (ICC_ProfileGrey and ICC_ProfileRGB).
+     * 
+     * @param profileHandle - should be valid handle to opened color profile
+     */
+    ICC_Profile(long profileHandle) {
+        this.profileHandle = profileHandle;
+        // A new object reference, need to add it.
+        NativeCMM.addHandle(this, profileHandle);
+    }
+
+    /**
+     * Writes the ICC_Profile to a file with the specified name.
+     * 
+     * @param fileName the file name.
+     * 
+     * @throws IOException signals that an I/O exception has occurred during
+     * writing or opening the file.
+     */
+    public void write(String fileName) throws IOException {
+        FileOutputStream oStream = new FileOutputStream(fileName);
+        oStream.write(getData());
+        oStream.close();
+    }
+
+    /**
+     * Serializable implementation.
+     * 
+     * @param s the s
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private void writeObject(ObjectOutputStream s) throws IOException {
+        s.defaultWriteObject();
+        s.writeObject(null);
+        s.writeObject(getData());
+    }
+
+    /**
+     * Serializable implementation.
+     * 
+     * @param s the s
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     * @throws ClassNotFoundException the class not found exception
+     */
+    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        String colorSpaceStr = (String)s.readObject();
+        byte[] data = (byte[])s.readObject();
+
+        if (colorSpaceStr != null) {
+            if (colorSpaceStr.equals("CS_sRGB")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_sRGB);
+            } else if (colorSpaceStr.equals("CS_GRAY")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_GRAY);
+            } else if (colorSpaceStr.equals("CS_LINEAR_RGB")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_LINEAR_RGB);
+            } else if (colorSpaceStr.equals("CS_CIEXYZ")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_CIEXYZ);
+            } else if (colorSpaceStr.equals("CS_PYCC")) { //$NON-NLS-1$
+                openedProfileObject = getInstance(ColorSpace.CS_PYCC);
+            } else {
+                openedProfileObject = ICC_Profile.getInstance(data);
+            }
+        } else {
+            openedProfileObject = ICC_Profile.getInstance(data);
+        }
+    }
+
+    /**
+     * Resolves instances being deserialized into instances registered with CMM.
+     * 
+     * @return ICC_Profile object for profile registered with CMM.
+     * 
+     * @throws ObjectStreamException if there is an error in the serialized 
+     * files or during the process of reading them.
+     */
+    protected Object readResolve() throws ObjectStreamException {
+        return openedProfileObject;
+    }
+
+    /**
+     * Writes the ICC_Profile to an OutputStream.
+     * 
+     * @param s the OutputStream.
+     * 
+     * @throws IOException signals that an I/O exception has occurred during
+     * writing or opening OutputStream.
+     */
+    public void write(OutputStream s) throws IOException {
+        s.write(getData());
+    }
+
+    /**
+     * Sets a tagged data element in the profile from a byte array. 
+     * 
+     * @param tagSignature the ICC tag signature for the data element to be set. 
+     * @param tagData the data to be set for the specified tag signature.
+     */
+    public void setData(int tagSignature, byte[] tagData) {
+        NativeCMM.cmmSetProfileElement(profileHandle, tagSignature, tagData);
+        // Remove cached header data if header is modified
+        if (tagSignature == icSigHead) {
+            headerData = null;
+        }
+    }
+
+    /**
+     * Gets a tagged data element from the profile as a byte array. 
+     * Elements are identified by tag signatures as defined in 
+     * the ICC specification. 
+     * 
+     * @param tagSignature the ICC tag signature for the data element to get.
+     * 
+     * @return a byte array that contains the tagged data element.
+     */
+    public byte[] getData(int tagSignature) {
+        int tagSize = 0;
+        try {
+            tagSize = NativeCMM.cmmGetProfileElementSize(
+                    profileHandle,
+                    tagSignature
+                );
+        } catch (CMMException e) {
+            // We'll get this exception if there's no element with
+            // the specified tag signature
+            return null;
+        }
+
+        byte[] data = new byte[tagSize];
+        NativeCMM.cmmGetProfileElement(profileHandle, tagSignature, data);
+        return data;
+    }
+
+    /**
+     * Gets a data byte array of this ICC_Profile.
+     * 
+     * @return a byte array that contains the ICC Profile data.
+     */
+    public byte[] getData() {
+        int profileSize = NativeCMM.cmmGetProfileSize(profileHandle);
+        byte[] data = new byte[profileSize];
+        NativeCMM.cmmGetProfile(profileHandle, data);
+        return data;
+    }
+
+    /**
+     * Frees the resources associated with an ICC_Profile object.
+     */
+    @Override
+    protected void finalize() {
+        if (profileHandle!=0 && !handleStolen) {
+            NativeCMM.cmmCloseProfile(profileHandle);
+        }
+
+        // Always remove because key no more exist
+        // when object is destroyed
+        NativeCMM.removeHandle(this);
+    }
+
+    /**
+     * Gets the profile class.
+     * 
+     * @return the profile class constant.
+     */
+    public int getProfileClass() {
+        int deviceClassSignature = getIntFromHeader(icHdrDeviceClass);
+
+        switch (deviceClassSignature) {
+            case icSigColorSpaceClass:
+                return CLASS_COLORSPACECONVERSION;
+            case icSigDisplayClass:
+                return CLASS_DISPLAY;
+            case icSigOutputClass:
+                return CLASS_OUTPUT;
+            case icSigInputClass:
+                return CLASS_INPUT;
+            case icSigLinkClass:
+                return CLASS_DEVICELINK;
+            case icSigAbstractClass:
+                return CLASS_ABSTRACT;
+            case icSigNamedColorClass:
+                return CLASS_NAMEDCOLOR;
+            default:
+        }
+
+        // Not an ICC profile class
+        // awt.15F=Profile class does not comply with ICC specification
+        throw new IllegalArgumentException(Messages.getString("awt.15F")); //$NON-NLS-1$
+        
+    }
+
+    /**
+     * Returns the color space type of the Profile Connection Space (PCS).
+     * 
+     * @return the PCS type.
+     */
+    public int getPCSType() {
+         return csFromSignature(getIntFromHeader(icHdrPcs));
+    }
+
+    /**
+     * Gets the number of components of this ICC Profile.
+     * 
+     * @return the number of components of this ICC Profile.
+     */
+    public int getNumComponents() {
+        switch (getIntFromHeader(icHdrColorSpace)) {
+            // The most common cases go first to increase speed
+            case icSigRgbData:
+            case icSigXYZData:
+            case icSigLabData:
+                return 3;
+            case icSigCmykData:
+                return 4;
+                // Then all other
+            case icSigGrayData:
+                return 1;
+            case icSigSpace2CLR:
+                return 2;
+            case icSigYCbCrData:
+            case icSigLuvData:
+            case icSigYxyData:
+            case icSigHlsData:
+            case icSigHsvData:
+            case icSigCmyData:
+            case icSigSpace3CLR:
+                return 3;
+            case icSigSpace4CLR:
+                return 4;
+            case icSigSpace5CLR:
+                return 5;
+            case icSigSpace6CLR:
+                return 6;
+            case icSigSpace7CLR:
+                return 7;
+            case icSigSpace8CLR:
+                return 8;
+            case icSigSpace9CLR:
+                return 9;
+            case icSigSpaceACLR:
+                return 10;
+            case icSigSpaceBCLR:
+                return 11;
+            case icSigSpaceCCLR:
+                return 12;
+            case icSigSpaceDCLR:
+                return 13;
+            case icSigSpaceECLR:
+                return 14;
+            case icSigSpaceFCLR:
+                return 15;
+            default:
+        }
+
+        // awt.160=Color space doesn't comply with ICC specification
+        throw new ProfileDataException(Messages.getString("awt.160") //$NON-NLS-1$
+        );
+    }
+
+    /**
+     * Gets the minor version of this ICC profile.
+     * 
+     * @return the minor version of this ICC profile.
+     */
+    public int getMinorVersion() {
+        return getByteFromHeader(icHdrVersion+1);
+    }
+
+    /**
+     * Gets the major version of this ICC profile.
+     * 
+     * @return the major version of this ICC profile.
+     */
+    public int getMajorVersion() {
+        return getByteFromHeader(icHdrVersion);
+    }
+
+    /**
+     * Gets the color space type of this ICC_Profile.
+     * 
+     * @return the color space type.
+     */
+    public int getColorSpaceType() {
+        return csFromSignature(getIntFromHeader(icHdrColorSpace));
+    }
+
+    /**
+     * Tries to open file at the specified path. Path entries can be 
+     * divided by a separator character.
+     * 
+     * @param path the path
+     * @param fileName the file name
+     * 
+     * @return the file input stream
+     */
+    private static FileInputStream tryPath(String path, String fileName) {
+        FileInputStream fiStream = null;
+
+        if (path == null) {
+            return null;
+        }
+
+        StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
+
+        while (st.hasMoreTokens()) {
+            String pathEntry = st.nextToken();
+            try {
+                fiStream = new FileInputStream(pathEntry + File.separatorChar + fileName);
+                if (fiStream != null) {
+                    return fiStream;
+                }
+            } catch (FileNotFoundException e) {}
+        }
+
+        return fiStream;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile from data in the specified file.
+     * 
+     * @param fileName the specified name of file with ICC profile data.
+     * 
+     * @return single instance of ICC_Profile.
+     * 
+     * @throws IOException signals that an I/O error occured while reading the file
+     * or the file doesn't exist.
+     */
+    public static ICC_Profile getInstance(String fileName) throws IOException {
+        final String fName = fileName; // to use in the privileged block
+
+        FileInputStream fiStream = (FileInputStream) AccessController.doPrivileged(
+                new PrivilegedAction<FileInputStream>() {
+                    public FileInputStream run() {
+                        FileInputStream fiStream = null;
+
+                        // Open absolute path
+                        try {
+                            fiStream = new FileInputStream(fName);
+                            if (fiStream != null) {
+                                return fiStream;
+                            }
+                        } catch (FileNotFoundException e) {}
+
+                        // Check java.iccprofile.path entries
+                        fiStream = tryPath(System.getProperty("java.iccprofile.path"), fName); //$NON-NLS-1$
+                        if (fiStream != null) {
+                            return fiStream;
+                        }
+
+                        // Check java.class.path entries
+                        fiStream = tryPath(System.getProperty("java.class.path"), fName); //$NON-NLS-1$
+                        if (fiStream != null) {
+                            return fiStream;
+                        }
+
+                        // Check directory with java sample profiles
+                        String home = System.getProperty("java.home"); //$NON-NLS-1$
+                        if (home != null) {
+                            fiStream = tryPath(
+                                    home + File.separatorChar +
+                                    "lib" + File.separatorChar + "cmm", fName //$NON-NLS-1$ //$NON-NLS-2$
+                            );
+                        }
+
+                        return fiStream;
+                    }
+                });
+
+        if (fiStream == null) {
+            // awt.161=Unable to open file {0}
+            throw new IOException(Messages.getString("awt.161", fileName)); //$NON-NLS-1$
+        }
+
+        ICC_Profile pf = getInstance(fiStream);
+        fiStream.close();
+        return pf;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile with data in
+     * the specified InputStream.
+     * 
+     * @param s the InputStream with ICC profile data.
+     * 
+     * @return single instance of ICC_Profile.
+     * 
+     * @throws IOException if an I/O exception has occurred during reading 
+     * from InputStream.
+     * @throws IllegalArgumentException if the file does not contain valid 
+     * ICC Profile data.
+     */
+    public static ICC_Profile getInstance(InputStream s) throws IOException {
+        byte[] header = new byte[headerSize];
+        // awt.162=Invalid ICC Profile Data
+        String invalidDataMessage = Messages.getString("awt.162"); //$NON-NLS-1$
+
+        // Get header from the input stream
+        if (s.read(header) != headerSize) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        // Check the profile data for consistency
+        if (
+                ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrMagic) !=
+                headerMagicNumber
+        ) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        // Get profile size from header, create an array for profile data
+        int profileSize = ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrSize);
+        byte[] profileData = new byte[profileSize];
+
+        // Copy header into it
+        System.arraycopy(header, 0, profileData, 0, headerSize);
+
+        // Read the profile itself
+        if (
+                s.read(profileData, headerSize, profileSize - headerSize) !=
+                profileSize - headerSize
+        ) {
+            throw new IllegalArgumentException(invalidDataMessage);
+        }
+
+        return getInstance(profileData);
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile from the specified data in 
+     * a byte array.
+     * 
+     * @param data the byte array of ICC profile.
+     * 
+     * @return single instance of ICC_Profile from the specified data in 
+     * a byte array.
+     * 
+     * @throws IllegalArgumentException if the file does not contain valid 
+     * ICC Profile data.
+     */
+    public static ICC_Profile getInstance(byte[] data) {
+        ICC_Profile res = null;
+
+        try {
+            res = new ICC_Profile(data);
+        } catch (CMMException e) {
+            // awt.162=Invalid ICC Profile Data
+            throw new IllegalArgumentException(Messages.getString("awt.162")); //$NON-NLS-1$
+        }
+
+      if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) { //$NON-NLS-1$ //$NON-NLS-2$
+        try {
+            if ( res.getColorSpaceType () == ColorSpace.TYPE_RGB &&
+                 res.getDataSize(icSigMediaWhitePointTag) > 0 &&
+                 res.getDataSize(icSigRedColorantTag) > 0 &&
+                 res.getDataSize(icSigGreenColorantTag) > 0 &&
+                 res.getDataSize(icSigBlueColorantTag) > 0 &&
+                 res.getDataSize(icSigRedTRCTag) > 0 &&
+                 res.getDataSize(icSigGreenTRCTag) > 0 &&
+                 res.getDataSize(icSigBlueTRCTag) > 0
+                ) {
+                res = new ICC_ProfileRGB(res.getProfileHandle());
+            } else if ( res.getColorSpaceType () == ColorSpace.TYPE_GRAY &&
+                        res.getDataSize(icSigMediaWhitePointTag) > 0 &&
+                        res.getDataSize(icSigGrayTRCTag) > 0
+                ) {
+                res = new ICC_ProfileGray (res.getProfileHandle());
+            }
+
+        } catch (CMMException e) { /* return res in this case */ }
+      }
+
+      return res;
+    }
+
+    /**
+     * Gets the single instance of ICC_Profile with the specific color space
+     * defined by the ColorSpace class: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ,
+     * CS_PYCC, CS_GRAY.
+     * 
+     * @param cspace the type of color space defined in the ColorSpace class.
+     * 
+     * @return single instance of ICC_Profile.
+     * 
+     * @throws IllegalArgumentException is not one of the defined color 
+     * space types.
+     */
+    public static ICC_Profile getInstance(int cspace) {
+    try {
+      switch (cspace) {
+
+      case ColorSpace.CS_sRGB:
+        if (sRGBProfile == null) {
+            sRGBProfile = getInstance("sRGB.pf"); //$NON-NLS-1$
+        }
+        return sRGBProfile;
+
+      case ColorSpace.CS_CIEXYZ:
+        if (xyzProfile == null) {
+            xyzProfile = getInstance("CIEXYZ.pf"); //$NON-NLS-1$
+        }
+        return xyzProfile;
+
+      case ColorSpace.CS_GRAY:
+        if (grayProfile == null) {
+            grayProfile = getInstance("GRAY.pf"); //$NON-NLS-1$
+        }
+        return grayProfile;
+
+      case ColorSpace.CS_PYCC:
+        if (pyccProfile == null) {
+            pyccProfile = getInstance("PYCC.pf"); //$NON-NLS-1$
+        }
+        return pyccProfile;
+
+      case ColorSpace.CS_LINEAR_RGB:
+        if (linearRGBProfile == null) {
+            linearRGBProfile = getInstance("LINEAR_RGB.pf"); //$NON-NLS-1$
+        }
+        return linearRGBProfile;
+      }
+
+    } catch (IOException e) {
+        // awt.163=Can't open color profile 
+        throw new IllegalArgumentException(Messages.getString("Can't open color profile")); //$NON-NLS-1$
+    }
+
+    // awt.164=Not a predefined color space
+    throw new IllegalArgumentException(Messages.getString("Not a predefined color space")); //$NON-NLS-1$
+  }
+
+    /**
+     * Reads an integer from the profile header at the specified position.
+     * 
+     * @param idx - offset in bytes from the beginning of the header
+     * 
+     * @return the int from header
+     */
+    private int getIntFromHeader(int idx) {
+        if (headerData == null) {
+            headerData = getData(icSigHead);
+        }
+
+        return  ((headerData[idx]   & 0xFF) << 24)|
+                  ((headerData[idx+1] & 0xFF) << 16)|
+                  ((headerData[idx+2] & 0xFF) << 8) |
+                  ((headerData[idx+3] & 0xFF));
+    }
+
+    /**
+     * Reads byte from the profile header at the specified position.
+     * 
+     * @param idx - offset in bytes from the beginning of the header
+     * 
+     * @return the byte from header
+     */
+    private byte getByteFromHeader(int idx) {
+        if (headerData == null) {
+            headerData = getData(icSigHead);
+        }
+
+        return headerData[idx];
+    }
+
+    /**
+     * Converts ICC color space signature to the java predefined
+     * color space type.
+     * 
+     * @param signature the signature
+     * 
+     * @return the int
+     */
+    private int csFromSignature(int signature) {
+        switch (signature) {
+            case icSigRgbData:
+                return ColorSpace.TYPE_RGB;
+            case icSigXYZData:
+                return ColorSpace.TYPE_XYZ;
+            case icSigCmykData:
+                return ColorSpace.TYPE_CMYK;
+            case icSigLabData:
+                return ColorSpace.TYPE_Lab;
+            case icSigGrayData:
+                return ColorSpace.TYPE_GRAY;
+            case icSigHlsData:
+                return ColorSpace.TYPE_HLS;
+            case icSigLuvData:
+                return ColorSpace.TYPE_Luv;
+            case icSigYCbCrData:
+                return ColorSpace.TYPE_YCbCr;
+            case icSigYxyData:
+                return ColorSpace.TYPE_Yxy;
+            case icSigHsvData:
+                return ColorSpace.TYPE_HSV;
+            case icSigCmyData:
+                return ColorSpace.TYPE_CMY;
+            case icSigSpace2CLR:
+                return ColorSpace.TYPE_2CLR;
+            case icSigSpace3CLR:
+                return ColorSpace.TYPE_3CLR;
+            case icSigSpace4CLR:
+                return ColorSpace.TYPE_4CLR;
+            case icSigSpace5CLR:
+                return ColorSpace.TYPE_5CLR;
+            case icSigSpace6CLR:
+                return ColorSpace.TYPE_6CLR;
+            case icSigSpace7CLR:
+                return ColorSpace.TYPE_7CLR;
+            case icSigSpace8CLR:
+                return ColorSpace.TYPE_8CLR;
+            case icSigSpace9CLR:
+                return ColorSpace.TYPE_9CLR;
+            case icSigSpaceACLR:
+                return ColorSpace.TYPE_ACLR;
+            case icSigSpaceBCLR:
+                return ColorSpace.TYPE_BCLR;
+            case icSigSpaceCCLR:
+                return ColorSpace.TYPE_CCLR;
+            case icSigSpaceDCLR:
+                return ColorSpace.TYPE_DCLR;
+            case icSigSpaceECLR:
+                return ColorSpace.TYPE_ECLR;
+            case icSigSpaceFCLR:
+                return ColorSpace.TYPE_FCLR;
+            default:
+        }
+
+        // awt.165=Color space doesn't comply with ICC specification
+        throw new IllegalArgumentException (Messages.getString("awt.165")); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the profile handle.
+     * 
+     * @return the profile handle
+     */
+    private long getProfileHandle() {
+        handleStolen = true;
+        return profileHandle;
+    }
+
+    /**
+     * Gets the data size.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the data size
+     */
+    private int getDataSize(int tagSignature) {
+        return NativeCMM.cmmGetProfileElementSize(
+                profileHandle,
+                tagSignature
+            );
+    }
+
+    /**
+     * Reads XYZ value from the tag data.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the XYZ value
+     */
+    float[] getXYZValue(int tagSignature) {
+        float[] res = new float[3];
+        byte[] data = getData(tagSignature);
+
+        // Convert from ICC s15Fixed16Number type
+        // 1 (float) = 0x10000 (s15Fixed16Number),
+        // hence dividing by 0x10000
+        res[0] = ICC_ProfileHelper.getIntFromByteArray(data, 0) / 65536.f;
+        res[1] = ICC_ProfileHelper.getIntFromByteArray(data, 4) / 65536.f;
+        res[2] = ICC_ProfileHelper.getIntFromByteArray(data, 8) / 65536.f;
+
+        return res;
+    }
+
+    /**
+     * Gets the media white point.
+     * 
+     * @return the media white point
+     */
+    float[] getMediaWhitePoint() {
+        return getXYZValue(icSigMediaWhitePointTag);
+    }
+
+    /**
+     * If TRC is not a table returns gamma via return value
+     * and sets dataTRC to null. If TRC is a table returns 0
+     * and fills dataTRC with values.
+     * 
+     * @param tagSignature the tag signature
+     * @param dataTRC the data trc
+     * 
+     * @return - gamma or zero if TRC is a table
+     */
+    private float getGammaOrTRC(int tagSignature, short[] dataTRC) {
+        byte[] data = getData(tagSignature);
+        int trcSize = ICC_ProfileHelper.getIntFromByteArray(data, icCurveCount);
+
+        dataTRC = null;
+
+        if (trcSize == 0) {
+            return 1.0f;
+        }
+
+        if (trcSize == 1) {
+            // Cast from ICC u8Fixed8Number to float
+            return ICC_ProfileHelper.getShortFromByteArray(data, icCurveData) / 256.f;
+        }
+
+        // TRC is a table
+        dataTRC = new short[trcSize];
+        for (int i = 0, pos = icCurveData; i < trcSize; i++, pos += 2) {
+            dataTRC[i] = ICC_ProfileHelper.getShortFromByteArray(data, pos);
+        }
+        return 0;
+    }
+
+    /**
+     * Gets the gamma.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the gamma
+     */
+    float getGamma(int tagSignature) {
+        short[] dataTRC = null;
+        float gamma = getGammaOrTRC(tagSignature, dataTRC);
+
+        if (dataTRC == null) {
+            return gamma;
+        }
+        // awt.166=TRC is not a simple gamma value.
+        throw new ProfileDataException(Messages.getString("awt.166")); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the tRC.
+     * 
+     * @param tagSignature the tag signature
+     * 
+     * @return the tRC
+     */
+    short[] getTRC(int tagSignature) {
+        short[] dataTRC = null;
+        getGammaOrTRC(tagSignature, dataTRC);
+
+        if (dataTRC == null) {
+            // awt.167=TRC is a gamma value, not a table.
+            throw new ProfileDataException(Messages.getString("awt.167")); //$NON-NLS-1$
+        }
+        return dataTRC;
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileGray.java b/awt/java/awt/color/ICC_ProfileGray.java
new file mode 100644
index 0000000..f009b18
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileGray.java
@@ -0,0 +1,68 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The ICC_ProfileGray class represent profiles with TYPE_GRAY color space type,
+ * and includes the grayTRCTag and mediaWhitePointTag tags. 
+ * 
+ * The gray component can be transformed from a GRAY device profile color space 
+ * to the CIEXYZ Profile through the tone reproduction curve (TRC): 
+ * <p>PCSY = grayTRC[deviceGray]
+ */
+public class ICC_ProfileGray extends ICC_Profile {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -1124721290732002649L;
+
+    /**
+     * Instantiates a new iC c_ profile gray.
+     * 
+     * @param profileHandle the profile handle
+     */
+    ICC_ProfileGray(long profileHandle) {
+        super(profileHandle);
+    }
+
+    /**
+     * Gets the TRC as an array of shorts.
+     * 
+     * @return a short array of the TRC.
+     */
+    public short[] getTRC() {
+        return super.getTRC(icSigGrayTRCTag);
+    }
+
+    @Override
+    public float[] getMediaWhitePoint() {
+        return super.getMediaWhitePoint();
+    }
+
+    /**
+     * Gets a gamma value representing the tone reproduction curve (TRC).
+     * 
+     * @return the gamma value representing the tone reproduction curve (TRC).
+     */
+    public float getGamma() {
+        return super.getGamma(icSigGrayTRCTag);
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileRGB.java b/awt/java/awt/color/ICC_ProfileRGB.java
new file mode 100644
index 0000000..beb1a0c
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileRGB.java
@@ -0,0 +1,122 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ICC_ProfileRGB class represents profiles with RGB color space type and 
+ * contains the redColorantTag, greenColorantTag, blueColorantTag, redTRCTag, 
+ * greenTRCTag, blueTRCTag, and mediaWhitePointTag tags.
+ */
+public class ICC_ProfileRGB extends ICC_Profile {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8505067385152579334L;
+
+    /**
+     * Instantiates a new iC c_ profile rgb.
+     * 
+     * @param profileHandle the profile handle
+     */
+    ICC_ProfileRGB(long profileHandle) {
+        super(profileHandle);
+    }
+
+    /** The Constant REDCOMPONENT indicates the red component. */
+    public static final int REDCOMPONENT = 0;
+
+    /** The Constant GREENCOMPONENT indicates the green component. */
+    public static final int GREENCOMPONENT = 1;
+
+    /** The Constant BLUECOMPONENT indicates the blue component. */
+    public static final int BLUECOMPONENT = 2;
+
+    // awt.15E=Unknown component. Must be REDCOMPONENT, GREENCOMPONENT or BLUECOMPONENT.
+    /** The Constant UNKNOWN_COMPONENT_MSG. */
+    private static final String UNKNOWN_COMPONENT_MSG = Messages
+            .getString("awt.15E"); //$NON-NLS-1$
+
+    @Override
+    public short[] getTRC(int component) {
+        switch (component) {
+            case REDCOMPONENT:
+                return super.getTRC(icSigRedTRCTag);
+            case GREENCOMPONENT:
+                return super.getTRC(icSigGreenTRCTag);
+            case BLUECOMPONENT:
+                return super.getTRC(icSigBlueTRCTag);
+            default:
+        }
+
+        throw new IllegalArgumentException(UNKNOWN_COMPONENT_MSG);
+    }
+
+    @Override
+    public float getGamma(int component) {
+        switch (component) {
+            case REDCOMPONENT:
+                return super.getGamma(icSigRedTRCTag);
+            case GREENCOMPONENT:
+                return super.getGamma(icSigGreenTRCTag);
+            case BLUECOMPONENT:
+                return super.getGamma(icSigBlueTRCTag);
+            default:
+        }
+
+        throw new IllegalArgumentException(UNKNOWN_COMPONENT_MSG);
+    }
+
+    /**
+     * Gets a float matrix which contains the X, Y, and Z components of 
+     * the profile's redColorantTag, greenColorantTag, and blueColorantTag.
+     * 
+     * @return a float matrix which contains the X, Y, and Z components of 
+     * the profile's redColorantTag, greenColorantTag, and blueColorantTag.
+     */
+    public float[][] getMatrix() {
+        float [][] m = new float[3][3]; // The matrix
+
+        float[] redXYZ = getXYZValue(icSigRedColorantTag);
+        float[] greenXYZ = getXYZValue(icSigGreenColorantTag);
+        float[] blueXYZ = getXYZValue(icSigBlueColorantTag);
+
+        m[0][0] = redXYZ[0];
+        m[1][0] = redXYZ[1];
+        m[2][0] = redXYZ[2];
+
+        m[0][1] = greenXYZ[0];
+        m[1][1] = greenXYZ[1];
+        m[2][1] = greenXYZ[2];
+
+        m[0][2] = blueXYZ[0];
+        m[1][2] = blueXYZ[1];
+        m[2][2] = blueXYZ[2];
+
+        return m;
+    }
+
+    @Override
+    public float[] getMediaWhitePoint() {
+        return super.getMediaWhitePoint();
+    }
+}
+
diff --git a/awt/java/awt/color/ICC_ProfileStub.java b/awt/java/awt/color/ICC_ProfileStub.java
new file mode 100644
index 0000000..bc04c8a
--- /dev/null
+++ b/awt/java/awt/color/ICC_ProfileStub.java
@@ -0,0 +1,173 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.color;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectStreamException;
+import java.io.OutputStream;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+final class ICC_ProfileStub extends ICC_Profile {
+    private static final long serialVersionUID = 501389760875253507L;
+
+    transient int colorspace;
+
+    public ICC_ProfileStub(int csSpecifier) {
+        switch (csSpecifier) {
+            case ColorSpace.CS_sRGB:
+            case ColorSpace.CS_CIEXYZ:
+            case ColorSpace.CS_LINEAR_RGB:
+            case ColorSpace.CS_PYCC:
+            case ColorSpace.CS_GRAY:
+                break;
+            default:
+                // awt.15D=Invalid colorspace
+                throw new IllegalArgumentException(Messages.getString("awt.15D")); //$NON-NLS-1$
+        }
+        colorspace = csSpecifier;
+    }
+
+    @Override
+    public void write(String fileName) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    /**
+     * Serializable implementation
+     *
+     * @throws ObjectStreamException
+     */
+    private Object writeReplace() throws ObjectStreamException {
+        return loadProfile();
+    }
+
+    @Override
+    public void write(OutputStream s) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public void setData(int tagSignature, byte[] tagData) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public byte[] getData(int tagSignature) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public byte[] getData() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    protected void finalize() {
+    }
+
+    @Override
+    public int getProfileClass() {
+        return CLASS_COLORSPACECONVERSION;
+    }
+
+    @Override
+    public int getPCSType() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getNumComponents() {
+        switch (colorspace) {
+            case ColorSpace.CS_sRGB:
+            case ColorSpace.CS_CIEXYZ:
+            case ColorSpace.CS_LINEAR_RGB:
+            case ColorSpace.CS_PYCC:
+                return 3;
+            case ColorSpace.CS_GRAY:
+                return 1;
+            default:
+                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public int getMinorVersion() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getMajorVersion() {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getColorSpaceType() {
+        switch (colorspace) {
+            case ColorSpace.CS_sRGB:
+            case ColorSpace.CS_LINEAR_RGB:
+                return ColorSpace.TYPE_RGB;
+            case ColorSpace.CS_CIEXYZ:
+                return ColorSpace.TYPE_XYZ;
+            case ColorSpace.CS_PYCC:
+                return ColorSpace.TYPE_3CLR;
+            case ColorSpace.CS_GRAY:
+                return ColorSpace.TYPE_GRAY;
+            default:
+                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+        }
+    }
+
+    public static ICC_Profile getInstance(String fileName) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public static ICC_Profile getInstance(InputStream s) throws IOException {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public static ICC_Profile getInstance(byte[] data) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public static ICC_Profile getInstance(int cspace) {
+        throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+    }
+
+    public ICC_Profile loadProfile() {
+        switch (colorspace) {
+            case ColorSpace.CS_sRGB:
+                return ICC_Profile.getInstance(ColorSpace.CS_sRGB);
+            case ColorSpace.CS_GRAY:
+                return ICC_Profile.getInstance(ColorSpace.CS_GRAY);
+            case ColorSpace.CS_CIEXYZ:
+                return ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
+            case ColorSpace.CS_LINEAR_RGB:
+                return ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB);
+            case ColorSpace.CS_PYCC:
+                return ICC_Profile.getInstance(ColorSpace.CS_PYCC);
+            default:
+                throw new UnsupportedOperationException("Stub cannot perform this operation"); //$NON-NLS-1$
+        }
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/color/ProfileDataException.java b/awt/java/awt/color/ProfileDataException.java
new file mode 100644
index 0000000..ca169fe
--- /dev/null
+++ b/awt/java/awt/color/ProfileDataException.java
@@ -0,0 +1,42 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package java.awt.color;
+
+/**
+ * The ProfileDataException class represents an error which occurs 
+ * while accessing or processing an ICC_Profile object.
+ */
+public class ProfileDataException extends RuntimeException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 7286140888240322498L;
+
+    /**
+     * Instantiates a new profile data exception with detailed message.
+     * 
+     * @param s the detailed message.
+     */
+    public ProfileDataException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/event/AWTEventListener.java b/awt/java/awt/event/AWTEventListener.java
new file mode 100644
index 0000000..f621c9b
--- /dev/null
+++ b/awt/java/awt/event/AWTEventListener.java
@@ -0,0 +1,30 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.util.EventListener;
+
+public interface AWTEventListener extends EventListener {
+
+    public void eventDispatched(AWTEvent event);
+
+}
diff --git a/awt/java/awt/event/AWTEventListenerProxy.java b/awt/java/awt/event/AWTEventListenerProxy.java
new file mode 100644
index 0000000..5ee5e59
--- /dev/null
+++ b/awt/java/awt/event/AWTEventListenerProxy.java
@@ -0,0 +1,52 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+import java.util.EventListenerProxy;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class AWTEventListenerProxy extends EventListenerProxy implements AWTEventListener {
+
+    private AWTEventListener listener;
+    private long eventMask;
+
+    public AWTEventListenerProxy(long eventMask, AWTEventListener listener) {
+        super(listener);
+
+        // awt.193=Listener can't be zero
+        assert listener != null : Messages.getString("awt.193"); //$NON-NLS-1$
+
+        this.listener = listener;
+        this.eventMask = eventMask;
+    }
+
+    public void eventDispatched(AWTEvent evt) {
+        listener.eventDispatched(evt);
+    }
+
+    public long getEventMask() {
+        return eventMask;
+    }
+
+}
diff --git a/awt/java/awt/event/ActionEvent.java b/awt/java/awt/event/ActionEvent.java
new file mode 100644
index 0000000..c32fc4b
--- /dev/null
+++ b/awt/java/awt/event/ActionEvent.java
@@ -0,0 +1,108 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+public class ActionEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -7671078796273832149L;
+
+    public static final int SHIFT_MASK = 1;
+
+    public static final int CTRL_MASK = 2;
+
+    public static final int META_MASK = 4;
+
+    public static final int ALT_MASK = 8;
+
+    public static final int ACTION_FIRST = 1001;
+
+    public static final int ACTION_LAST = 1001;
+
+    public static final int ACTION_PERFORMED = 1001;
+
+    private long when;
+    private int modifiers;
+    private String command;
+
+    public ActionEvent(Object source, int id, String command) {
+        this(source, id, command, 0);
+    }
+
+    public ActionEvent(Object source, int id, String command, int modifiers) {
+        this(source, id, command, 0l, modifiers);
+    }
+
+    public ActionEvent(Object source, int id, String command, long when, int modifiers) {
+        super(source, id);
+
+        this.command = command;
+        this.when = when;
+        this.modifiers = modifiers;
+    }
+
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    public String getActionCommand() {
+        return command;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ActionEvent e = new ActionEvent(new Component(){},
+         *       ActionEvent.ACTION_PERFORMED, "Command",
+         *       ActionEvent.SHIFT_MASK|ActionEvent.CTRL_MASK|
+         *       ActionEvent.META_MASK|ActionEvent.ALT_MASK);
+         * System.out.println(e);
+         */
+
+        String idString = (id == ACTION_PERFORMED) ? 
+                          "ACTION_PERFORMED" : "unknown type"; //$NON-NLS-1$ //$NON-NLS-2$
+        String modifiersString = ""; //$NON-NLS-1$
+
+        if ((modifiers & SHIFT_MASK) > 0) {
+            modifiersString += "Shift"; //$NON-NLS-1$
+        }
+        if ((modifiers & CTRL_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Ctrl" : "+Ctrl"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiers & META_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Meta" : "+Meta"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiers & ALT_MASK) > 0) {
+            modifiersString += modifiersString.length() == 0 ? "Alt" : "+Alt"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return (idString + ",cmd=" + command + ",when=" + when +  //$NON-NLS-1$ //$NON-NLS-2$
+                ",modifiers=" + modifiersString); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ActionListener.java b/awt/java/awt/event/ActionListener.java
new file mode 100644
index 0000000..473d2b6
--- /dev/null
+++ b/awt/java/awt/event/ActionListener.java
@@ -0,0 +1,29 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ActionListener extends EventListener {
+
+    public void actionPerformed(ActionEvent e);
+
+}
diff --git a/awt/java/awt/event/AdjustmentEvent.java b/awt/java/awt/event/AdjustmentEvent.java
new file mode 100644
index 0000000..a2b11a8
--- /dev/null
+++ b/awt/java/awt/event/AdjustmentEvent.java
@@ -0,0 +1,117 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Adjustable;
+
+public class AdjustmentEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 5700290645205279921L;
+
+    public static final int ADJUSTMENT_FIRST = 601;
+
+    public static final int ADJUSTMENT_LAST = 601;
+
+    public static final int ADJUSTMENT_VALUE_CHANGED = 601;
+
+    public static final int UNIT_INCREMENT = 1;
+
+    public static final int UNIT_DECREMENT = 2;
+
+    public static final int BLOCK_DECREMENT = 3;
+
+    public static final int BLOCK_INCREMENT = 4;
+
+    public static final int TRACK = 5;
+
+    private int type;
+    private int value;
+    private boolean isAdjusting;
+
+    public AdjustmentEvent(Adjustable source, int id, int type, int value) {
+        this(source, id, type, value, false);
+    }
+
+    public AdjustmentEvent(Adjustable source, int id, int type, int value, 
+                           boolean isAdjusting) {
+        super(source, id);
+        this.type = type;
+        this.value = value;
+        this.isAdjusting = isAdjusting;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public int getAdjustmentType() {
+        return type;
+    }
+
+    public boolean getValueIsAdjusting() {
+        return isAdjusting;
+    }
+
+    public Adjustable getAdjustable() {
+        return (Adjustable) source;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * AdjustmentEvent e = new AdjustmentEvent(new Scrollbar(), 
+         *       AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 
+         *       AdjustmentEvent.UNIT_INCREMENT, 1);
+         * System.out.println(e);
+         */
+
+        String idString = (id == ADJUSTMENT_VALUE_CHANGED ?
+                "ADJUSTMENT_VALUE_CHANGED" : "unknown type"); //$NON-NLS-1$ //$NON-NLS-2$
+        String adjType = null;
+
+        switch (type) {
+        case UNIT_INCREMENT:
+            adjType = "UNIT_INCREMENT"; //$NON-NLS-1$
+            break;
+        case UNIT_DECREMENT:
+            adjType = "UNIT_DECREMENT"; //$NON-NLS-1$
+            break;
+        case BLOCK_INCREMENT:
+            adjType = "BLOCK_INCREMENT"; //$NON-NLS-1$
+            break;
+        case BLOCK_DECREMENT:
+            adjType = "BLOCK_DECREMENT"; //$NON-NLS-1$
+            break;
+        case TRACK:
+            adjType = "TRACK"; //$NON-NLS-1$
+            break;
+        default:
+            adjType = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + ",adjType=" + adjType + ",value=" + value + //$NON-NLS-1$ //$NON-NLS-2$
+                ",isAdjusting=" + isAdjusting); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/AdjustmentListener.java b/awt/java/awt/event/AdjustmentListener.java
new file mode 100644
index 0000000..ef7c378
--- /dev/null
+++ b/awt/java/awt/event/AdjustmentListener.java
@@ -0,0 +1,29 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface AdjustmentListener extends EventListener {
+
+    public void adjustmentValueChanged(AdjustmentEvent e);
+
+}
diff --git a/awt/java/awt/event/ComponentAdapter.java b/awt/java/awt/event/ComponentAdapter.java
new file mode 100644
index 0000000..4f0bd90
--- /dev/null
+++ b/awt/java/awt/event/ComponentAdapter.java
@@ -0,0 +1,40 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class ComponentAdapter implements ComponentListener {
+
+    public ComponentAdapter() {
+    }
+
+    public void componentHidden(ComponentEvent e) {
+    }
+
+    public void componentMoved(ComponentEvent e) {
+    }
+
+    public void componentResized(ComponentEvent e) {
+    }
+
+    public void componentShown(ComponentEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/ComponentEvent.java b/awt/java/awt/event/ComponentEvent.java
new file mode 100644
index 0000000..d0bca54
--- /dev/null
+++ b/awt/java/awt/event/ComponentEvent.java
@@ -0,0 +1,82 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+
+public class ComponentEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 8101406823902992965L;
+
+    public static final int COMPONENT_FIRST = 100;
+
+    public static final int COMPONENT_LAST = 103;
+
+    public static final int COMPONENT_MOVED = 100;
+
+    public static final int COMPONENT_RESIZED = 101;
+
+    public static final int COMPONENT_SHOWN = 102;
+
+    public static final int COMPONENT_HIDDEN = 103;
+
+    public ComponentEvent(Component source, int id) {
+        super(source, id);
+    }
+
+    public Component getComponent() {
+        return (Component) source;
+    }
+    
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ComponentEvent e = new ComponentEvent(new Button("Button"), 
+         *          ComponentEvent.COMPONENT_SHOWN);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        Component c = getComponent();
+
+        switch (id) {
+        case COMPONENT_MOVED:
+            idString = "COMPONENT_MOVED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_RESIZED:
+            idString = "COMPONENT_RESIZED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_SHOWN:
+            return "COMPONENT_SHOWN"; //$NON-NLS-1$
+        case COMPONENT_HIDDEN:
+            return "COMPONENT_HIDDEN"; //$NON-NLS-1$
+        default:
+            return "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + " (" + c.getX() + "," + c.getY() +  //$NON-NLS-1$ //$NON-NLS-2$
+                " " + c.getWidth()+ "x" + c.getHeight() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+}
diff --git a/awt/java/awt/event/ComponentListener.java b/awt/java/awt/event/ComponentListener.java
new file mode 100644
index 0000000..147e9e0
--- /dev/null
+++ b/awt/java/awt/event/ComponentListener.java
@@ -0,0 +1,35 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ComponentListener extends EventListener {
+
+    public void componentHidden(ComponentEvent e);
+
+    public void componentMoved(ComponentEvent e);
+
+    public void componentResized(ComponentEvent e);
+
+    public void componentShown(ComponentEvent e);
+
+}
diff --git a/awt/java/awt/event/ContainerAdapter.java b/awt/java/awt/event/ContainerAdapter.java
new file mode 100644
index 0000000..12dc3de
--- /dev/null
+++ b/awt/java/awt/event/ContainerAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class ContainerAdapter implements ContainerListener {
+
+    public ContainerAdapter() {
+    }
+
+    public void componentAdded(ContainerEvent e) {
+    }
+
+    public void componentRemoved(ContainerEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/ContainerEvent.java b/awt/java/awt/event/ContainerEvent.java
new file mode 100644
index 0000000..1a1055c
--- /dev/null
+++ b/awt/java/awt/event/ContainerEvent.java
@@ -0,0 +1,83 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+//???AWT: import java.awt.Container;
+
+public class ContainerEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -4114942250539772041L;
+
+    public static final int CONTAINER_FIRST = 300;
+
+    public static final int CONTAINER_LAST = 301;
+
+    public static final int COMPONENT_ADDED = 300;
+
+    public static final int COMPONENT_REMOVED = 301;
+
+    private Component child;
+
+    public ContainerEvent(Component src, int id, Component child) {
+        super(src, id);
+        this.child = child;
+    }
+
+    public Component getChild() {
+        return child;
+    }
+
+    //???AWT
+    /*
+    public Container getContainer() {
+        return (Container) source;
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * ContainerEvent e = new ContainerEvent(new Panel(),
+         *          ContainerEvent.COMPONENT_ADDED,
+         *          new Button("Button"));
+         * System.out.println(e);
+         */
+
+        String idString = null;
+
+        switch (id) {
+        case COMPONENT_ADDED:
+            idString = "COMPONENT_ADDED"; //$NON-NLS-1$
+            break;
+        case COMPONENT_REMOVED:
+            idString = "COMPONENT_REMOVED"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString + ",child=" + child.getName()); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ContainerListener.java b/awt/java/awt/event/ContainerListener.java
new file mode 100644
index 0000000..bf47664
--- /dev/null
+++ b/awt/java/awt/event/ContainerListener.java
@@ -0,0 +1,31 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ContainerListener extends EventListener {
+
+    public void componentAdded(ContainerEvent e);
+
+    public void componentRemoved(ContainerEvent e);
+
+}
diff --git a/awt/java/awt/event/FocusAdapter.java b/awt/java/awt/event/FocusAdapter.java
new file mode 100644
index 0000000..3489e11
--- /dev/null
+++ b/awt/java/awt/event/FocusAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class FocusAdapter implements FocusListener {
+
+    public FocusAdapter() {
+    }
+
+    public void focusGained(FocusEvent e) {
+    }
+
+    public void focusLost(FocusEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/FocusEvent.java b/awt/java/awt/event/FocusEvent.java
new file mode 100644
index 0000000..1db5263
--- /dev/null
+++ b/awt/java/awt/event/FocusEvent.java
@@ -0,0 +1,90 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+public class FocusEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = 523753786457416396L;
+
+    public static final int FOCUS_FIRST = 1004;
+
+    public static final int FOCUS_LAST = 1005;
+
+    public static final int FOCUS_GAINED = 1004;
+
+    public static final int FOCUS_LOST = 1005;
+
+    private boolean temporary;
+    private Component opposite;
+
+    public FocusEvent(Component source, int id) {
+        this(source, id, false);
+    }
+
+    public FocusEvent(Component source, int id, boolean temporary) {
+        this(source, id, temporary, null);
+    }
+
+    public FocusEvent(Component source, int id, boolean temporary, Component opposite) {
+        super(source, id);
+        this.temporary = temporary;
+        this.opposite = opposite;
+    }
+
+    public Component getOppositeComponent() {
+        return opposite;
+    }
+
+    public boolean isTemporary() {
+        return temporary;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * FocusEvent e = new FocusEvent(new Button("Button0"),
+         *       FocusEvent.FOCUS_GAINED, false, new Button("Button1"));
+         * System.out.println(e);
+         */
+
+        String idString = null;
+
+        switch (id) {
+        case FOCUS_GAINED:
+            idString = "FOCUS_GAINED"; //$NON-NLS-1$
+            break;
+        case FOCUS_LOST:
+            idString = "FOCUS_LOST"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return (idString +
+                (temporary ? ",temporary" : ",permanent") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",opposite=" + opposite); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/FocusListener.java b/awt/java/awt/event/FocusListener.java
new file mode 100644
index 0000000..ee98d90
--- /dev/null
+++ b/awt/java/awt/event/FocusListener.java
@@ -0,0 +1,31 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface FocusListener extends EventListener {
+
+    public void focusGained(FocusEvent e);
+
+    public void focusLost(FocusEvent e);
+
+}
diff --git a/awt/java/awt/event/HierarchyBoundsAdapter.java b/awt/java/awt/event/HierarchyBoundsAdapter.java
new file mode 100644
index 0000000..24e3d9d
--- /dev/null
+++ b/awt/java/awt/event/HierarchyBoundsAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class HierarchyBoundsAdapter implements HierarchyBoundsListener {
+
+    public HierarchyBoundsAdapter() {
+    }
+
+    public void ancestorMoved(HierarchyEvent e) {
+    }
+
+    public void ancestorResized(HierarchyEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/HierarchyBoundsListener.java b/awt/java/awt/event/HierarchyBoundsListener.java
new file mode 100644
index 0000000..4288f52
--- /dev/null
+++ b/awt/java/awt/event/HierarchyBoundsListener.java
@@ -0,0 +1,31 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface HierarchyBoundsListener extends EventListener {
+
+    public void ancestorMoved(HierarchyEvent e);
+
+    public void ancestorResized(HierarchyEvent e);
+
+}
diff --git a/awt/java/awt/event/HierarchyEvent.java b/awt/java/awt/event/HierarchyEvent.java
new file mode 100644
index 0000000..1881667
--- /dev/null
+++ b/awt/java/awt/event/HierarchyEvent.java
@@ -0,0 +1,148 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+//???AWT: import java.awt.Container;
+
+public class HierarchyEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -5337576970038043990L;
+
+    public static final int HIERARCHY_FIRST = 1400;
+
+    public static final int HIERARCHY_CHANGED = 1400;
+
+    public static final int ANCESTOR_MOVED = 1401;
+
+    public static final int ANCESTOR_RESIZED = 1402;
+
+    public static final int HIERARCHY_LAST = 1402;
+
+    public static final int PARENT_CHANGED = 1;
+
+    public static final int DISPLAYABILITY_CHANGED = 2;
+
+    public static final int SHOWING_CHANGED = 4;
+
+    //???AWT: private Container changedParent;
+    private Component changed;
+    private long changeFlag;
+
+    //???AWT
+    /*
+    public HierarchyEvent(Component source, int id, Component changed, 
+                          Container changedParent) {
+        this(source, id, changed, changedParent, 0l);
+    }
+    */
+
+    //???AWT
+    /*
+    public HierarchyEvent(Component source, int id, Component changed,
+            Container changedParent, long changeFlags) {
+        super(source, id);
+
+        this.changed = changed;
+        this.changedParent = changedParent;
+        this.changeFlag = changeFlags;
+    }
+    */
+    //???AWT: Fake constructor, should be as above.
+    public HierarchyEvent(Component source, int id, Component changed,
+            Object changedParent, long changeFlags) {
+        super(source, id);
+
+//        this.changed = changed;
+//        this.changedParent = changedParent;
+//        this.changeFlag = changeFlags;
+    }
+    
+    public Component getComponent() {
+        return (Component) source;
+    }
+
+    public long getChangeFlags() {
+        return changeFlag;
+    }
+
+    public Component getChanged() {
+        return changed;
+    }
+
+    //???AWT
+    /*
+    public Container getChangedParent() {
+        return changedParent;
+
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * HierarchyEvent e = new HierarchyEvent(new Button("Button"),
+         *          HierarchyEvent.HIERARCHY_CHANGED,
+         *          new Panel(), new Container());
+         * System.out.println(e);
+         */
+        String paramString = null;
+
+        switch (id) {
+        case HIERARCHY_CHANGED:
+            paramString = "HIERARCHY_CHANGED"; //$NON-NLS-1$
+            break;
+        case ANCESTOR_MOVED:
+            paramString = "ANCESTOR_MOVED"; //$NON-NLS-1$
+            break;
+        case ANCESTOR_RESIZED:
+            paramString = "ANCESTOR_RESIZED"; //$NON-NLS-1$
+            break;
+        default:
+            paramString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString += " ("; //$NON-NLS-1$
+
+        if (id == HIERARCHY_CHANGED) {
+            if ((changeFlag & PARENT_CHANGED) > 0) {
+                paramString += "PARENT_CHANGED,"; //$NON-NLS-1$
+            }
+            if ((changeFlag & DISPLAYABILITY_CHANGED) > 0) {
+                paramString += "DISPLAYABILITY_CHANGED,"; //$NON-NLS-1$
+            }
+            if ((changeFlag & SHOWING_CHANGED) > 0) {
+                paramString += "SHOWING_CHANGED,"; //$NON-NLS-1$
+            }
+        }
+
+        //???AWT
+        /*
+        return paramString + "changed=" + changed +  //$NON-NLS-1$
+                ",changedParent=" + changedParent + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+        */
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/HierarchyListener.java b/awt/java/awt/event/HierarchyListener.java
new file mode 100644
index 0000000..e01ba11
--- /dev/null
+++ b/awt/java/awt/event/HierarchyListener.java
@@ -0,0 +1,29 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface HierarchyListener extends EventListener {
+
+    public void hierarchyChanged(HierarchyEvent e);
+
+}
diff --git a/awt/java/awt/event/InputEvent.java b/awt/java/awt/event/InputEvent.java
new file mode 100644
index 0000000..c98382d
--- /dev/null
+++ b/awt/java/awt/event/InputEvent.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.
+ */
+/**
+ * @author Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+public abstract class InputEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -2482525981698309786L;
+
+    public static final int SHIFT_MASK = 1;
+
+    public static final int CTRL_MASK = 2;
+
+    public static final int META_MASK = 4;
+
+    public static final int ALT_MASK = 8;
+
+    public static final int ALT_GRAPH_MASK = 32;
+
+    public static final int BUTTON1_MASK = 16;
+
+    public static final int BUTTON2_MASK = 8;
+
+    public static final int BUTTON3_MASK = 4;
+
+    public static final int SHIFT_DOWN_MASK = 64;
+
+    public static final int CTRL_DOWN_MASK = 128;
+
+    public static final int META_DOWN_MASK = 256;
+
+    public static final int ALT_DOWN_MASK = 512;
+
+    public static final int BUTTON1_DOWN_MASK = 1024;
+
+    public static final int BUTTON2_DOWN_MASK = 2048;
+
+    public static final int BUTTON3_DOWN_MASK = 4096;
+
+    public static final int ALT_GRAPH_DOWN_MASK = 8192;
+
+    private static final int DOWN_MASKS = SHIFT_DOWN_MASK | CTRL_DOWN_MASK |
+            META_DOWN_MASK | ALT_DOWN_MASK | BUTTON1_DOWN_MASK |
+            BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK | ALT_GRAPH_DOWN_MASK;
+
+    private long when;
+    private int modifiersEx;
+
+    public static String getModifiersExText(int modifiers/*Ex*/) {
+        return MouseEvent.addMouseModifiersExText(
+                KeyEvent.getKeyModifiersExText(modifiers), modifiers);
+    }
+
+    static int extractExFlags(int modifiers) {
+        int exFlags = modifiers & DOWN_MASKS;
+
+        if ((modifiers & SHIFT_MASK) != 0) {
+            exFlags |= SHIFT_DOWN_MASK;
+        }
+        if ((modifiers & CTRL_MASK) != 0) {
+            exFlags |= CTRL_DOWN_MASK;
+        }
+        if ((modifiers & META_MASK) != 0) {
+            exFlags |= META_DOWN_MASK;
+        }
+        if ((modifiers & ALT_MASK) != 0) {
+            exFlags |= ALT_DOWN_MASK;
+        }
+        if ((modifiers & ALT_GRAPH_MASK) != 0) {
+            exFlags |= ALT_GRAPH_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON1_MASK) != 0) {
+            exFlags |= BUTTON1_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON2_MASK) != 0) {
+            exFlags |= BUTTON2_DOWN_MASK;
+        }
+        if ((modifiers & BUTTON3_MASK) != 0) {
+            exFlags |= BUTTON3_DOWN_MASK;
+        }
+
+        return exFlags;
+    }
+
+    InputEvent(Component source, int id, long when, int modifiers) {
+        super(source, id);
+
+        this.when = when;
+        modifiersEx = extractExFlags(modifiers);
+    }
+
+    public int getModifiers() {
+        int modifiers = 0;
+
+        if ((modifiersEx & SHIFT_DOWN_MASK) != 0) {
+            modifiers |= SHIFT_MASK;
+        }
+        if ((modifiersEx & CTRL_DOWN_MASK) != 0) {
+            modifiers |= CTRL_MASK;
+        }
+        if ((modifiersEx & META_DOWN_MASK) != 0) {
+            modifiers |= META_MASK;
+        }
+        if ((modifiersEx & ALT_DOWN_MASK) != 0) {
+            modifiers |= ALT_MASK;
+        }
+        if ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0) {
+            modifiers |= ALT_GRAPH_MASK;
+        }
+        if ((modifiersEx & BUTTON1_DOWN_MASK) != 0) {
+            modifiers |= BUTTON1_MASK;
+        }
+        if ((modifiersEx & BUTTON2_DOWN_MASK) != 0) {
+            modifiers |= BUTTON2_MASK;
+        }
+        if ((modifiersEx & BUTTON3_DOWN_MASK) != 0) {
+            modifiers |= BUTTON3_MASK;
+        }
+
+        return modifiers;
+    }
+
+    public int getModifiersEx() {
+        return modifiersEx;
+    }
+
+    void setModifiers(int modifiers) {
+        modifiersEx = extractExFlags(modifiers);
+    }
+
+    public boolean isAltDown() {
+        return ((modifiersEx & ALT_DOWN_MASK) != 0);
+    }
+
+    public boolean isAltGraphDown() {
+        return ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0);
+    }
+
+    public boolean isControlDown() {
+        return ((modifiersEx & CTRL_DOWN_MASK) != 0);
+    }
+
+    public boolean isMetaDown() {
+        return ((modifiersEx & META_DOWN_MASK) != 0);
+    }
+
+    public boolean isShiftDown() {
+        return ((modifiersEx & SHIFT_DOWN_MASK) != 0);
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public void consume() {
+        super.consume();
+    }
+
+    @Override
+    public boolean isConsumed() {
+        return super.isConsumed();
+    }
+
+}
diff --git a/awt/java/awt/event/InputMethodEvent.java b/awt/java/awt/event/InputMethodEvent.java
new file mode 100644
index 0000000..a5cac4e
--- /dev/null
+++ b/awt/java/awt/event/InputMethodEvent.java
@@ -0,0 +1,150 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.Component;
+import java.awt.font.TextHitInfo;
+import java.text.AttributedCharacterIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class InputMethodEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 4727190874778922661L;
+
+    public static final int INPUT_METHOD_FIRST = 1100;
+
+    public static final int INPUT_METHOD_TEXT_CHANGED = 1100;
+
+    public static final int CARET_POSITION_CHANGED = 1101;
+
+    public static final int INPUT_METHOD_LAST = 1101;
+
+    private AttributedCharacterIterator text;
+    private TextHitInfo visiblePosition;
+    private TextHitInfo caret;
+    private int committedCharacterCount;
+    private long when;
+
+    public InputMethodEvent(Component src, int id,
+                            TextHitInfo caret, 
+                            TextHitInfo visiblePos) {
+        this(src, id, null, 0, caret, visiblePos);
+    }
+
+    public InputMethodEvent(Component src, int id, 
+                            AttributedCharacterIterator text,
+                            int commitedCharCount,
+                            TextHitInfo caret, 
+                            TextHitInfo visiblePos) {
+        this(src, id, 0l, text, commitedCharCount, caret, visiblePos);
+    }
+
+    public InputMethodEvent(Component src, int id, long when,
+                            AttributedCharacterIterator text, 
+                            int committedCharacterCount,
+                            TextHitInfo caret,
+                            TextHitInfo visiblePos) {
+        super(src, id);
+
+        if ((id < INPUT_METHOD_FIRST) || (id > INPUT_METHOD_LAST)) {
+            // awt.18E=Wrong event id
+            throw new IllegalArgumentException(Messages.getString("awt.18E")); //$NON-NLS-1$
+        }
+        if ((id == CARET_POSITION_CHANGED) && (text != null)) {
+            // awt.18F=Text must be null for CARET_POSITION_CHANGED
+            throw new IllegalArgumentException(Messages.getString("awt.18F")); //$NON-NLS-1$
+        }
+        if ((text != null) &&
+                ((committedCharacterCount < 0) ||
+                 (committedCharacterCount > 
+                        (text.getEndIndex() - text.getBeginIndex())))) {
+            // awt.190=Wrong committedCharacterCount
+            throw new IllegalArgumentException(Messages.getString("awt.190")); //$NON-NLS-1$
+        }
+
+        this.when = when;
+        this.text = text;
+        this.caret = caret;
+        this.visiblePosition = visiblePos;
+        this.committedCharacterCount = committedCharacterCount;
+    }
+
+    public TextHitInfo getCaret() {
+        return caret;
+    }
+
+    public int getCommittedCharacterCount() {
+        return committedCharacterCount;
+    }
+
+    public AttributedCharacterIterator getText() {
+        return text;
+    }
+
+    public TextHitInfo getVisiblePosition() {
+        return visiblePosition;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public void consume() {
+        super.consume();
+    }
+
+    @Override
+    public boolean isConsumed() {
+        return super.isConsumed();
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * InputMethodEvent e = new InputMethodEvent(new Component(){},
+         *          InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
+         *          TextHitInfo.leading(1), TextHitInfo.trailing(2));
+         * System.out.println(e);
+         */
+        String typeString = null;
+
+        switch (id) {
+        case INPUT_METHOD_TEXT_CHANGED:
+            typeString = "INPUT_METHOD_TEXT_CHANGED"; //$NON-NLS-1$
+            break;
+        case CARET_POSITION_CHANGED:
+            typeString = "CARET_POSITION_CHANGED"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return typeString + ",text=" + text +  //$NON-NLS-1$
+                ",commitedCharCount=" + committedCharacterCount + //$NON-NLS-1$
+                ",caret=" + caret + ",visiblePosition=" + visiblePosition; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/InputMethodListener.java b/awt/java/awt/event/InputMethodListener.java
new file mode 100644
index 0000000..0ab6918
--- /dev/null
+++ b/awt/java/awt/event/InputMethodListener.java
@@ -0,0 +1,31 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface InputMethodListener extends EventListener {
+
+    public void caretPositionChanged(InputMethodEvent e);
+
+    public void inputMethodTextChanged(InputMethodEvent e);
+
+}
diff --git a/awt/java/awt/event/InvocationEvent.java b/awt/java/awt/event/InvocationEvent.java
new file mode 100644
index 0000000..59346ed
--- /dev/null
+++ b/awt/java/awt/event/InvocationEvent.java
@@ -0,0 +1,132 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.ActiveEvent;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class InvocationEvent extends AWTEvent implements ActiveEvent {
+
+    private static final long serialVersionUID = 436056344909459450L;
+
+    public static final int INVOCATION_FIRST = 1200;
+
+    public static final int INVOCATION_DEFAULT = 1200;
+
+    public static final int INVOCATION_LAST = 1200;
+
+    protected Runnable runnable;
+
+    protected Object notifier;
+
+    protected boolean catchExceptions;
+
+    private long when;
+    private Throwable throwable;
+
+    public InvocationEvent(Object source, Runnable runnable) {
+        this(source, runnable, null, false);
+    }
+
+    public InvocationEvent(Object source, Runnable runnable, 
+                           Object notifier, boolean catchExceptions) {
+        this(source, INVOCATION_DEFAULT, runnable, notifier, catchExceptions);
+    }
+
+    protected InvocationEvent(Object source, int id, Runnable runnable,
+            Object notifier, boolean catchExceptions)
+    {
+        super(source, id);
+
+        // awt.18C=Cannot invoke null runnable
+        assert runnable != null : Messages.getString("awt.18C"); //$NON-NLS-1$
+
+        if (source == null) {
+            // awt.18D=Source is null
+            throw new IllegalArgumentException(Messages.getString("awt.18D")); //$NON-NLS-1$
+        }
+        this.runnable = runnable;
+        this.notifier = notifier;
+        this.catchExceptions = catchExceptions;
+
+        throwable = null;
+        when = System.currentTimeMillis();
+    }
+
+    public void dispatch() {
+        if (!catchExceptions) {
+            runAndNotify();
+        } else {
+            try {
+                runAndNotify();
+            } catch (Throwable t) {
+                throwable = t;
+            }
+        }
+    }
+
+    private void runAndNotify() {
+        if (notifier != null) {
+            synchronized(notifier) {
+                try {
+                    runnable.run();
+                } finally {
+                    notifier.notifyAll();
+                }
+            }
+        } else {
+            runnable.run();
+        }
+    }
+
+    public Exception getException() {
+        return (throwable != null && throwable instanceof Exception) ?
+                (Exception)throwable : null;
+    }
+
+    public Throwable getThrowable() {
+        return throwable;
+    }
+
+    public long getWhen() {
+        return when;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * InvocationEvent e = new InvocationEvent(new Component(){},
+         *       new Runnable() { public void run(){} });
+         * System.out.println(e);
+         */
+
+        return ((id == INVOCATION_DEFAULT ? "INVOCATION_DEFAULT" : "unknown type") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",runnable=" + runnable + //$NON-NLS-1$
+                ",notifier=" + notifier + //$NON-NLS-1$
+                ",catchExceptions=" + catchExceptions + //$NON-NLS-1$
+                ",when=" + when); //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/ItemEvent.java b/awt/java/awt/event/ItemEvent.java
new file mode 100644
index 0000000..842da14
--- /dev/null
+++ b/awt/java/awt/event/ItemEvent.java
@@ -0,0 +1,90 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+import java.awt.ItemSelectable;
+
+public class ItemEvent extends AWTEvent {
+
+    private static final long serialVersionUID = -608708132447206933L;
+
+    public static final int ITEM_FIRST = 701;
+
+    public static final int ITEM_LAST = 701;
+
+    public static final int ITEM_STATE_CHANGED = 701;
+
+    public static final int SELECTED = 1;
+
+    public static final int DESELECTED = 2;
+
+    private Object item;
+    private int stateChange;
+
+    public ItemEvent(ItemSelectable source, int id, Object item, int stateChange) {
+        super(source, id);
+
+        this.item = item;
+        this.stateChange = stateChange;
+    }
+
+    public Object getItem() {
+        return item;
+    }
+
+    public int getStateChange() {
+        return stateChange;
+    }
+
+    public ItemSelectable getItemSelectable() {
+        return (ItemSelectable) source;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * Checkbox c = new Checkbox("Checkbox", true);
+         * ItemEvent e = new ItemEvent(c, ItemEvent.ITEM_STATE_CHANGED, 
+         *                             c, ItemEvent.SELECTED);
+         * System.out.println(e);
+         */
+
+        String stateString = null;
+
+        switch (stateChange) {
+        case SELECTED:
+            stateString = "SELECTED"; //$NON-NLS-1$
+            break;
+        case DESELECTED:
+            stateString = "DESELECTED"; //$NON-NLS-1$
+            break;
+        default:
+            stateString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return ((id == ITEM_STATE_CHANGED ? "ITEM_STATE_CHANGED" : "unknown type") + //$NON-NLS-1$ //$NON-NLS-2$
+                ",item=" + item + ",stateChange=" + stateString); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/ItemListener.java b/awt/java/awt/event/ItemListener.java
new file mode 100644
index 0000000..33633be
--- /dev/null
+++ b/awt/java/awt/event/ItemListener.java
@@ -0,0 +1,29 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface ItemListener extends EventListener {
+
+    public void itemStateChanged(ItemEvent e);
+
+}
diff --git a/awt/java/awt/event/KeyAdapter.java b/awt/java/awt/event/KeyAdapter.java
new file mode 100644
index 0000000..423b5c9
--- /dev/null
+++ b/awt/java/awt/event/KeyAdapter.java
@@ -0,0 +1,37 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class KeyAdapter implements KeyListener {
+
+    public KeyAdapter() {
+    }
+
+    public void keyPressed(KeyEvent e) {
+    }
+
+    public void keyReleased(KeyEvent e) {
+    }
+
+    public void keyTyped(KeyEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/KeyEvent.java b/awt/java/awt/event/KeyEvent.java
new file mode 100644
index 0000000..056c64c
--- /dev/null
+++ b/awt/java/awt/event/KeyEvent.java
@@ -0,0 +1,681 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Toolkit;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class KeyEvent extends InputEvent {
+
+    private static final long serialVersionUID = -2352130953028126954L;
+
+    public static final int KEY_FIRST = 400;
+
+    public static final int KEY_LAST = 402;
+
+    public static final int KEY_TYPED = 400;
+
+    public static final int KEY_PRESSED = 401;
+
+    public static final int KEY_RELEASED = 402;
+
+    public static final int VK_ENTER = 10;
+
+    public static final int VK_BACK_SPACE = 8;
+
+    public static final int VK_TAB = 9;
+
+    public static final int VK_CANCEL = 3;
+
+    public static final int VK_CLEAR = 12;
+
+    public static final int VK_SHIFT = 16;
+
+    public static final int VK_CONTROL = 17;
+
+    public static final int VK_ALT = 18;
+
+    public static final int VK_PAUSE = 19;
+
+    public static final int VK_CAPS_LOCK = 20;
+
+    public static final int VK_ESCAPE = 27;
+
+    public static final int VK_SPACE = 32;
+
+    public static final int VK_PAGE_UP = 33;
+
+    public static final int VK_PAGE_DOWN = 34;
+
+    public static final int VK_END = 35;
+
+    public static final int VK_HOME = 36;
+
+    public static final int VK_LEFT = 37;
+
+    public static final int VK_UP = 38;
+
+    public static final int VK_RIGHT = 39;
+
+    public static final int VK_DOWN = 40;
+
+    public static final int VK_COMMA = 44;
+
+    public static final int VK_MINUS = 45;
+
+    public static final int VK_PERIOD = 46;
+
+    public static final int VK_SLASH = 47;
+
+    public static final int VK_0 = 48;
+
+    public static final int VK_1 = 49;
+
+    public static final int VK_2 = 50;
+
+    public static final int VK_3 = 51;
+
+    public static final int VK_4 = 52;
+
+    public static final int VK_5 = 53;
+
+    public static final int VK_6 = 54;
+
+    public static final int VK_7 = 55;
+
+    public static final int VK_8 = 56;
+
+    public static final int VK_9 = 57;
+
+    public static final int VK_SEMICOLON = 59;
+
+    public static final int VK_EQUALS = 61;
+
+    public static final int VK_A = 65;
+
+    public static final int VK_B = 66;
+
+    public static final int VK_C = 67;
+
+    public static final int VK_D = 68;
+
+    public static final int VK_E = 69;
+
+    public static final int VK_F = 70;
+
+    public static final int VK_G = 71;
+
+    public static final int VK_H = 72;
+
+    public static final int VK_I = 73;
+
+    public static final int VK_J = 74;
+
+    public static final int VK_K = 75;
+
+    public static final int VK_L = 76;
+
+    public static final int VK_M = 77;
+
+    public static final int VK_N = 78;
+
+    public static final int VK_O = 79;
+
+    public static final int VK_P = 80;
+
+    public static final int VK_Q = 81;
+
+    public static final int VK_R = 82;
+
+    public static final int VK_S = 83;
+
+    public static final int VK_T = 84;
+
+    public static final int VK_U = 85;
+
+    public static final int VK_V = 86;
+
+    public static final int VK_W = 87;
+
+    public static final int VK_X = 88;
+
+    public static final int VK_Y = 89;
+
+    public static final int VK_Z = 90;
+
+    public static final int VK_OPEN_BRACKET = 91;
+
+    public static final int VK_BACK_SLASH = 92;
+
+    public static final int VK_CLOSE_BRACKET = 93;
+
+    public static final int VK_NUMPAD0 = 96;
+
+    public static final int VK_NUMPAD1 = 97;
+
+    public static final int VK_NUMPAD2 = 98;
+
+    public static final int VK_NUMPAD3 = 99;
+
+    public static final int VK_NUMPAD4 = 100;
+
+    public static final int VK_NUMPAD5 = 101;
+
+    public static final int VK_NUMPAD6 = 102;
+
+    public static final int VK_NUMPAD7 = 103;
+
+    public static final int VK_NUMPAD8 = 104;
+
+    public static final int VK_NUMPAD9 = 105;
+
+    public static final int VK_MULTIPLY = 106;
+
+    public static final int VK_ADD = 107;
+
+    public static final int VK_SEPARATER = 108;
+
+    public static final int VK_SEPARATOR = 108;
+
+    public static final int VK_SUBTRACT = 109;
+
+    public static final int VK_DECIMAL = 110;
+
+    public static final int VK_DIVIDE = 111;
+
+    public static final int VK_DELETE = 127;
+
+    public static final int VK_NUM_LOCK = 144;
+
+    public static final int VK_SCROLL_LOCK = 145;
+
+    public static final int VK_F1 = 112;
+
+    public static final int VK_F2 = 113;
+
+    public static final int VK_F3 = 114;
+
+    public static final int VK_F4 = 115;
+
+    public static final int VK_F5 = 116;
+
+    public static final int VK_F6 = 117;
+
+    public static final int VK_F7 = 118;
+
+    public static final int VK_F8 = 119;
+
+    public static final int VK_F9 = 120;
+
+    public static final int VK_F10 = 121;
+
+    public static final int VK_F11 = 122;
+
+    public static final int VK_F12 = 123;
+
+    public static final int VK_F13 = 61440;
+
+    public static final int VK_F14 = 61441;
+
+    public static final int VK_F15 = 61442;
+
+    public static final int VK_F16 = 61443;
+
+    public static final int VK_F17 = 61444;
+
+    public static final int VK_F18 = 61445;
+
+    public static final int VK_F19 = 61446;
+
+    public static final int VK_F20 = 61447;
+
+    public static final int VK_F21 = 61448;
+
+    public static final int VK_F22 = 61449;
+
+    public static final int VK_F23 = 61450;
+
+    public static final int VK_F24 = 61451;
+
+    public static final int VK_PRINTSCREEN = 154;
+
+    public static final int VK_INSERT = 155;
+
+    public static final int VK_HELP = 156;
+
+    public static final int VK_META = 157;
+
+    public static final int VK_BACK_QUOTE = 192;
+
+    public static final int VK_QUOTE = 222;
+
+    public static final int VK_KP_UP = 224;
+
+    public static final int VK_KP_DOWN = 225;
+
+    public static final int VK_KP_LEFT = 226;
+
+    public static final int VK_KP_RIGHT = 227;
+
+    public static final int VK_DEAD_GRAVE = 128;
+
+    public static final int VK_DEAD_ACUTE = 129;
+
+    public static final int VK_DEAD_CIRCUMFLEX = 130;
+
+    public static final int VK_DEAD_TILDE = 131;
+
+    public static final int VK_DEAD_MACRON = 132;
+
+    public static final int VK_DEAD_BREVE = 133;
+
+    public static final int VK_DEAD_ABOVEDOT = 134;
+
+    public static final int VK_DEAD_DIAERESIS = 135;
+
+    public static final int VK_DEAD_ABOVERING = 136;
+
+    public static final int VK_DEAD_DOUBLEACUTE = 137;
+
+    public static final int VK_DEAD_CARON = 138;
+
+    public static final int VK_DEAD_CEDILLA = 139;
+
+    public static final int VK_DEAD_OGONEK = 140;
+
+    public static final int VK_DEAD_IOTA = 141;
+
+    public static final int VK_DEAD_VOICED_SOUND = 142;
+
+    public static final int VK_DEAD_SEMIVOICED_SOUND = 143;
+
+    public static final int VK_AMPERSAND = 150;
+
+    public static final int VK_ASTERISK = 151;
+
+    public static final int VK_QUOTEDBL = 152;
+
+    public static final int VK_LESS = 153;
+
+    public static final int VK_GREATER = 160;
+
+    public static final int VK_BRACELEFT = 161;
+
+    public static final int VK_BRACERIGHT = 162;
+
+    public static final int VK_AT = 512;
+
+    public static final int VK_COLON = 513;
+
+    public static final int VK_CIRCUMFLEX = 514;
+
+    public static final int VK_DOLLAR = 515;
+
+    public static final int VK_EURO_SIGN = 516;
+
+    public static final int VK_EXCLAMATION_MARK = 517;
+
+    public static final int VK_INVERTED_EXCLAMATION_MARK = 518;
+
+    public static final int VK_LEFT_PARENTHESIS = 519;
+
+    public static final int VK_NUMBER_SIGN = 520;
+
+    public static final int VK_PLUS = 521;
+
+    public static final int VK_RIGHT_PARENTHESIS = 522;
+
+    public static final int VK_UNDERSCORE = 523;
+
+    public static final int VK_FINAL = 24;
+
+    public static final int VK_WINDOWS = 524; 
+
+    public static final int VK_CONTEXT_MENU = 525;
+
+    public static final int VK_CONVERT = 28;
+
+    public static final int VK_NONCONVERT = 29;
+
+    public static final int VK_ACCEPT = 30;
+
+    public static final int VK_MODECHANGE = 31;
+
+    public static final int VK_KANA = 21;
+
+    public static final int VK_KANJI = 25;
+
+    public static final int VK_ALPHANUMERIC = 240;
+
+    public static final int VK_KATAKANA = 241;
+
+    public static final int VK_HIRAGANA = 242;
+
+    public static final int VK_FULL_WIDTH = 243;
+
+    public static final int VK_HALF_WIDTH = 244;
+
+    public static final int VK_ROMAN_CHARACTERS = 245;
+
+    public static final int VK_ALL_CANDIDATES = 256;
+
+    public static final int VK_PREVIOUS_CANDIDATE = 257;
+
+    public static final int VK_CODE_INPUT = 258;
+
+    public static final int VK_JAPANESE_KATAKANA = 259;
+
+    public static final int VK_JAPANESE_HIRAGANA = 260;
+
+    public static final int VK_JAPANESE_ROMAN = 261;
+
+    public static final int VK_KANA_LOCK = 262;
+
+    public static final int VK_INPUT_METHOD_ON_OFF = 263;
+
+    public static final int VK_CUT = 65489;
+
+    public static final int VK_COPY = 65485;
+
+    public static final int VK_PASTE = 65487;
+
+    public static final int VK_UNDO = 65483;
+
+    public static final int VK_AGAIN = 65481;
+
+    public static final int VK_FIND = 65488;
+
+    public static final int VK_PROPS = 65482;
+
+    public static final int VK_STOP = 65480;
+
+    public static final int VK_COMPOSE = 65312;
+
+    public static final int VK_ALT_GRAPH = 65406;
+
+    public static final int VK_BEGIN = 65368;
+
+    public static final int VK_UNDEFINED = 0;
+
+    public static final char CHAR_UNDEFINED = (char)(-1);
+
+    public static final int KEY_LOCATION_UNKNOWN = 0;
+
+    public static final int KEY_LOCATION_STANDARD = 1;
+
+    public static final int KEY_LOCATION_LEFT = 2;
+
+    public static final int KEY_LOCATION_RIGHT = 3;
+
+    public static final int KEY_LOCATION_NUMPAD = 4;
+
+    private int keyCode;
+    private char keyChar;
+    private int keyLocation;
+
+    public static String getKeyModifiersText(int modifiers) {
+        return getKeyModifiersExText(extractExFlags(modifiers));
+    }
+
+    static String getKeyModifiersExText(int modifiersEx) {
+        String text = ""; //$NON-NLS-1$
+
+        if ((modifiersEx & InputEvent.META_DOWN_MASK) != 0) {
+            text += Toolkit.getProperty("AWT.meta", "Meta"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.CTRL_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.control", "Ctrl"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.ALT_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.alt", "Alt"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.SHIFT_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.shift", "Shift"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.altGraph", "Alt Graph"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return text;
+    }
+
+    public static String getKeyText(int keyCode) {
+        String[] rawName = getPublicStaticFinalIntFieldName(keyCode); //$NON-NLS-1$
+
+        if ((rawName == null) || (rawName.length == 0)) {
+            return ("Unknown keyCode: " + (keyCode >= 0 ? "0x" : "-0x") + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    Integer.toHexString(Math.abs(keyCode)));
+        }
+
+        String propertyName = getPropertyName(rawName);
+        String defaultName = getDefaultName(rawName);
+
+        return Toolkit.getProperty(propertyName, defaultName);
+    }
+
+    private static String getDefaultName(String[] rawName) {
+        String name = ""; //$NON-NLS-1$
+
+        for (int i = 0; true; i++) {
+            String part = rawName[i];
+
+            name += new String(new char[] {part.charAt(0)}).toUpperCase() +
+                    part.substring(1).toLowerCase();
+
+            if (i == (rawName.length - 1)) {
+                break;
+            }
+            name += " "; //$NON-NLS-1$
+        }
+
+        return name;
+    }
+
+    private static String getPropertyName(String[] rawName) {
+        String name = rawName[0].toLowerCase();
+
+        for (int i = 1; i < rawName.length; i++) {
+            String part = rawName[i];
+
+            name += new String(new char[] {part.charAt(0)}).toUpperCase() +
+                    part.substring(1).toLowerCase();
+        }
+
+        return ("AWT." + name); //$NON-NLS-1$
+    }
+
+    private static String[] getPublicStaticFinalIntFieldName(int value) {
+        Field[] allFields = KeyEvent.class.getDeclaredFields();
+
+        try {
+            for (Field field : allFields) {
+                Class<?> ssalc = field.getType();
+                int modifiers = field.getModifiers();
+
+                if (ssalc.isPrimitive() && ssalc.getName().equals("int") && //$NON-NLS-1$
+                        Modifier.isFinal(modifiers) && Modifier.isPublic(modifiers) &&
+                        Modifier.isStatic(modifiers))
+                {
+                    if (field.getInt(null) == value){
+                        final String name = field.getName();
+                        final int prefixLength = name.indexOf("_") + 1;
+                        return name.substring(prefixLength).split("_"); //$NON-NLS-1$
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return null;
+    }
+
+    @Deprecated
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode) {
+        this(src, id, when, modifiers, keyCode,
+                (keyCode > (2 << 7) - 1) ? CHAR_UNDEFINED : (char) keyCode);
+    }
+
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode, char keyChar) {
+        this(src, id, when, modifiers, keyCode, keyChar, KEY_LOCATION_UNKNOWN);
+    }
+
+    public KeyEvent(Component src, int id,
+                    long when, int modifiers,
+                    int keyCode, char keyChar,
+                    int keyLocation) {
+        super(src, id, when, modifiers);
+
+        if (id == KEY_TYPED) {
+            if (keyCode != VK_UNDEFINED) {
+                // awt.191=Invalid keyCode for KEY_TYPED event, must be VK_UNDEFINED
+                throw new IllegalArgumentException(Messages.getString("awt.191")); //$NON-NLS-1$
+            }
+            if (keyChar == CHAR_UNDEFINED) {
+                // awt.192=Invalid keyChar for KEY_TYPED event, can't be CHAR_UNDEFINED
+                throw new IllegalArgumentException(Messages.getString("awt.192")); //$NON-NLS-1$
+            }
+        }
+        
+        if ((keyLocation < KEY_LOCATION_UNKNOWN)
+                || (keyLocation > KEY_LOCATION_NUMPAD)) {
+            // awt.297=Invalid keyLocation
+            throw new IllegalArgumentException(Messages.getString("awt.297")); //$NON-NLS-1$
+        }
+
+        this.keyChar = keyChar;
+        this.keyLocation = keyLocation;
+        this.keyCode = keyCode;
+    }
+
+    public int getKeyCode() {
+        return keyCode;
+    }
+
+    public void setKeyCode(int keyCode) {
+        this.keyCode = keyCode;
+    }
+
+    public char getKeyChar() {
+        return keyChar;
+    }
+
+    public void setKeyChar(char keyChar) {
+        this.keyChar = keyChar;
+    }
+
+    public int getKeyLocation() {
+        return keyLocation;
+    }
+
+    @Override
+    @Deprecated
+    public void setModifiers(int modifiers) {
+        super.setModifiers(modifiers);
+    }
+
+    public boolean isActionKey() {
+        return ((keyChar == CHAR_UNDEFINED) && (keyCode != VK_UNDEFINED) &&
+                !((keyCode == VK_ALT) || (keyCode == VK_ALT_GRAPH) ||
+                    (keyCode == VK_CONTROL) || (keyCode == VK_META) || (keyCode == VK_SHIFT)));
+    }
+
+    @Override
+    public String paramString() {
+        /*
+         * The format is based on 1.5 release behavior
+         * which can be revealed by the following code:
+         *
+         * KeyEvent e = new KeyEvent(new Component() {}, 
+         *       KeyEvent.KEY_PRESSED, 0, 
+         *       KeyEvent.CTRL_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK, 
+         *       KeyEvent.VK_A, 'A', KeyEvent.KEY_LOCATION_STANDARD);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        String locString = null;
+        String paramString = null;
+        String keyCharString = (keyChar == '\n') ?
+                keyCharString = getKeyText(VK_ENTER) : "'" + keyChar + "'"; //$NON-NLS-1$ //$NON-NLS-2$
+
+        switch (id) {
+        case KEY_PRESSED:
+            idString = "KEY_PRESSED"; //$NON-NLS-1$
+            break;
+        case KEY_RELEASED:
+            idString = "KEY_RELEASED"; //$NON-NLS-1$
+            break;
+        case KEY_TYPED:
+            idString = "KEY_TYPED"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        switch(keyLocation){
+        case KEY_LOCATION_STANDARD:
+            locString = "KEY_LOCATION_STANDARD"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_LEFT:
+            locString = "KEY_LOCATION_LEFT"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_RIGHT:
+            locString = "KEY_LOCATION_RIGHT"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_NUMPAD:
+            locString = "KEY_LOCATION_NUMPAD"; //$NON-NLS-1$
+            break;
+        case KEY_LOCATION_UNKNOWN:
+            locString = "KEY_LOCATION_UNKNOWN"; //$NON-NLS-1$
+            break;
+        default:
+            locString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString = idString + ",keyCode=" + keyCode; //$NON-NLS-1$
+        if (isActionKey()) {
+            paramString += "," + getKeyText(keyCode); //$NON-NLS-1$
+        } else {
+            paramString += ",keyChar=" + keyCharString; //$NON-NLS-1$
+        }
+        if (getModifiersEx() > 0) {
+            paramString += ",modifiers=" + getModifiersExText(getModifiersEx()) + //$NON-NLS-1$
+                    ",extModifiers=" + getModifiersExText(getModifiersEx()); //$NON-NLS-1$
+        }
+        paramString += ",keyLocation=" + locString; //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/KeyListener.java b/awt/java/awt/event/KeyListener.java
new file mode 100644
index 0000000..f20fc90
--- /dev/null
+++ b/awt/java/awt/event/KeyListener.java
@@ -0,0 +1,33 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface KeyListener extends EventListener {
+
+    public void keyPressed(KeyEvent e);
+
+    public void keyReleased(KeyEvent e);
+
+    public void keyTyped(KeyEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseAdapter.java b/awt/java/awt/event/MouseAdapter.java
new file mode 100644
index 0000000..4973956
--- /dev/null
+++ b/awt/java/awt/event/MouseAdapter.java
@@ -0,0 +1,43 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class MouseAdapter implements MouseListener {
+
+    public MouseAdapter() {
+    }
+
+    public void mouseClicked(MouseEvent e) {
+    }
+
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    public void mouseExited(MouseEvent e) {
+    }
+
+    public void mousePressed(MouseEvent e) {
+    }
+
+    public void mouseReleased(MouseEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/MouseEvent.java b/awt/java/awt/event/MouseEvent.java
new file mode 100644
index 0000000..0b776f9
--- /dev/null
+++ b/awt/java/awt/event/MouseEvent.java
@@ -0,0 +1,226 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.Toolkit;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class MouseEvent extends InputEvent {
+
+    private static final long serialVersionUID = -991214153494842848L;
+
+    public static final int MOUSE_FIRST = 500;
+
+    public static final int MOUSE_LAST = 507;
+
+    public static final int MOUSE_CLICKED = 500;
+
+    public static final int MOUSE_PRESSED = 501;
+
+    public static final int MOUSE_RELEASED = 502;
+
+    public static final int MOUSE_MOVED = 503;
+
+    public static final int MOUSE_ENTERED = 504;
+
+    public static final int MOUSE_EXITED = 505;
+
+    public static final int MOUSE_DRAGGED = 506;
+
+    public static final int MOUSE_WHEEL = 507;
+
+    public static final int NOBUTTON = 0;
+
+    public static final int BUTTON1 = 1;
+
+    public static final int BUTTON2 = 2;
+
+    public static final int BUTTON3 = 3;
+
+    private boolean popupTrigger;
+    private int clickCount;
+    private int button;
+    private int x;
+    private int y;
+
+    public static String getMouseModifiersText(int modifiers) {
+        final StringBuffer text = new StringBuffer();
+
+        if ((modifiers & META_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.meta", "Meta")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & SHIFT_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.shift", "Shift")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & CTRL_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.control", "Ctrl")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & ALT_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.alt", "Alt")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & ALT_GRAPH_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.altGraph", "Alt Graph")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON1_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button1", "Button1")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON2_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button2", "Button2")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+        if ((modifiers & BUTTON3_MASK) != 0) {
+            text.append(Toolkit.getProperty("AWT.button3", "Button3")).append("+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        return text.length() == 0 ? text.toString() : text.substring(0, text
+                .length() - 1);
+    }
+
+    static String addMouseModifiersExText(String text, int modifiersEx) {
+        if ((modifiersEx & InputEvent.BUTTON1_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button1", "Button1"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.BUTTON2_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button2", "Button2"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        if ((modifiersEx & InputEvent.BUTTON3_DOWN_MASK) != 0) {
+            text += ((text.length() > 0) ? "+" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                    Toolkit.getProperty("AWT.button3", "Button3"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        return text;
+    }
+
+    public MouseEvent(Component source, int id, long when,
+                      int modifiers, int x, int y,
+                      int clickCount, boolean popupTrigger) {
+        this(source, id, when, modifiers, x, y,
+             clickCount, popupTrigger, NOBUTTON);
+    }
+
+    public MouseEvent(Component source, int id, long when,
+                      int modifiers, int x, int y,
+                      int clickCount, boolean popupTrigger, int button) {
+        super(source, id, when, modifiers);
+
+        if ((button != NOBUTTON) && (button != BUTTON1) &&
+                (button != BUTTON2) && (button != BUTTON3)) {
+            // awt.18B=Invalid button value
+            throw new IllegalArgumentException(Messages.getString("awt.18B")); //$NON-NLS-1$
+        }
+
+        this.popupTrigger = popupTrigger;
+        this.clickCount = clickCount;
+        this.button = button;
+        this.x = x;
+        this.y = y;
+    }
+
+    public int getButton() {
+        return button;
+    }
+
+    public int getClickCount() {
+        return clickCount;
+    }
+
+    public Point getPoint() {
+        return new Point(x, y);
+    }
+
+    public int getX() {
+        return x;
+    }
+
+    public int getY() {
+        return y;
+    }
+
+    public boolean isPopupTrigger() {
+        return popupTrigger;
+    }
+
+    public void translatePoint(int x, int y) {
+        this.x += x;
+        this.y += y;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * MouseEvent e = new MouseEvent(new Component(){}, 
+         *          MouseEvent.MOUSE_PRESSED, 0, 
+         *          MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.CTRL_DOWN_MASK,
+         *          10, 20, 1, false, MouseEvent.BUTTON1);
+         * System.out.println(e);
+         */
+
+        String idString = null;
+        String paramString = null;
+
+        switch (id) {
+        case MOUSE_MOVED:
+            idString = "MOUSE_MOVED"; //$NON-NLS-1$
+            break;
+        case MOUSE_CLICKED:
+            idString = "MOUSE_CLICKED"; //$NON-NLS-1$
+            break;
+        case MOUSE_PRESSED:
+            idString = "MOUSE_PRESSED"; //$NON-NLS-1$
+            break;
+        case MOUSE_RELEASED:
+            idString = "MOUSE_RELEASED"; //$NON-NLS-1$
+            break;
+        case MOUSE_DRAGGED:
+            idString = "MOUSE_DRAGGED"; //$NON-NLS-1$
+            break;
+        case MOUSE_ENTERED:
+            idString = "MOUSE_ENTERED"; //$NON-NLS-1$
+            break;
+        case MOUSE_EXITED:
+            idString = "MOUSE_EXITED"; //$NON-NLS-1$
+            break;
+        case MOUSE_WHEEL:
+            idString = "MOUSE_WHEEL"; //$NON-NLS-1$
+            break;
+        default:
+            idString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString = idString + ",(" + getX() + "," + getY() + ")" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                ",button=" + button; //$NON-NLS-1$
+        if (getModifiersEx() > 0) {
+            paramString += 
+                    ",modifiers=" + getModifiersExText(getModifiersEx()) + //$NON-NLS-1$
+                    ",extModifiers=" + getModifiersExText(getModifiersEx()); //$NON-NLS-1$
+        }
+        paramString += ",clickCount=" + getClickCount(); //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/MouseListener.java b/awt/java/awt/event/MouseListener.java
new file mode 100644
index 0000000..5d32b0f
--- /dev/null
+++ b/awt/java/awt/event/MouseListener.java
@@ -0,0 +1,37 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface MouseListener extends EventListener {
+
+    public void mouseClicked(MouseEvent e);
+
+    public void mouseEntered(MouseEvent e);
+
+    public void mouseExited(MouseEvent e);
+
+    public void mousePressed(MouseEvent e);
+
+    public void mouseReleased(MouseEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseMotionAdapter.java b/awt/java/awt/event/MouseMotionAdapter.java
new file mode 100644
index 0000000..a4bebcc
--- /dev/null
+++ b/awt/java/awt/event/MouseMotionAdapter.java
@@ -0,0 +1,34 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class MouseMotionAdapter implements MouseMotionListener {
+
+    public MouseMotionAdapter() {
+    }
+
+    public void mouseDragged(MouseEvent e) {
+    }
+
+    public void mouseMoved(MouseEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/MouseMotionListener.java b/awt/java/awt/event/MouseMotionListener.java
new file mode 100644
index 0000000..a5c11da
--- /dev/null
+++ b/awt/java/awt/event/MouseMotionListener.java
@@ -0,0 +1,31 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface MouseMotionListener extends EventListener {
+
+    public void mouseDragged(MouseEvent e);
+
+    public void mouseMoved(MouseEvent e);
+
+}
diff --git a/awt/java/awt/event/MouseWheelEvent.java b/awt/java/awt/event/MouseWheelEvent.java
new file mode 100644
index 0000000..d3ac9d8
--- /dev/null
+++ b/awt/java/awt/event/MouseWheelEvent.java
@@ -0,0 +1,97 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+
+public class MouseWheelEvent extends MouseEvent {
+
+    private static final long serialVersionUID = -9187413581993563929L;
+
+    public static final int WHEEL_UNIT_SCROLL = 0;
+
+    public static final int WHEEL_BLOCK_SCROLL = 1;
+
+    private int wheelRotation;
+    private int scrollAmount;
+    private int scrollType;
+
+    public MouseWheelEvent(Component source, int id, long when, int modifiers,
+            int x, int y, int clickCount, boolean popupTrigger, int scrollType,
+            int scrollAmount, int wheelRotation) {
+        super(source, id, when, modifiers, x, y, clickCount, popupTrigger);
+
+        this.scrollType = scrollType;
+        this.scrollAmount = scrollAmount;
+        this.wheelRotation = wheelRotation;
+    }
+
+    public int getScrollAmount() {
+        return scrollAmount;
+    }
+
+    public int getScrollType() {
+        return scrollType;
+    }
+
+    public int getWheelRotation() {
+        return wheelRotation;
+    }
+
+    public int getUnitsToScroll() {
+        return (scrollAmount * wheelRotation);
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * MouseWheelEvent e = new MouseWheelEvent(new Component(){}, 
+         *          MouseWheelEvent.MOUSE_WHEEL, 0, 
+         *          MouseEvent.BUTTON1_DOWN_MASK|MouseEvent.CTRL_DOWN_MASK,
+         *          10, 20, 1, false, MouseWheelEvent.WHEEL_UNIT_SCROLL,
+         *          1, 3);
+         * System.out.println(e);
+         */
+
+        String paramString = super.paramString();
+        String typeString = null;
+
+        switch (scrollType) {
+        case WHEEL_UNIT_SCROLL:
+            typeString = "WHEEL_UNIT_SCROLL"; //$NON-NLS-1$
+            break;
+        case WHEEL_BLOCK_SCROLL:
+            typeString = "WHEEL_BLOCK_SCROLL"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        paramString += ",scrollType=" + typeString + //$NON-NLS-1$
+                ",scrollAmount=" + scrollAmount +  //$NON-NLS-1$
+                ",wheelRotation=" + wheelRotation; //$NON-NLS-1$
+
+        return paramString;
+    }
+
+}
diff --git a/awt/java/awt/event/MouseWheelListener.java b/awt/java/awt/event/MouseWheelListener.java
new file mode 100644
index 0000000..8ca1c8b
--- /dev/null
+++ b/awt/java/awt/event/MouseWheelListener.java
@@ -0,0 +1,29 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface MouseWheelListener extends EventListener {
+
+    public void mouseWheelMoved(MouseWheelEvent e);
+
+}
diff --git a/awt/java/awt/event/PaintEvent.java b/awt/java/awt/event/PaintEvent.java
new file mode 100644
index 0000000..d0573e1
--- /dev/null
+++ b/awt/java/awt/event/PaintEvent.java
@@ -0,0 +1,80 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.Component;
+import java.awt.Rectangle;
+
+public class PaintEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = 1267492026433337593L;
+
+    public static final int PAINT_FIRST = 800;
+
+    public static final int PAINT_LAST = 801;
+
+    public static final int PAINT = 800;
+
+    public static final int UPDATE = 801;
+
+    private Rectangle updateRect;
+
+    public PaintEvent(Component source, int id, Rectangle updateRect) {
+        super(source, id);
+
+        this.updateRect = updateRect;
+    }
+
+    public Rectangle getUpdateRect() {
+        return updateRect;
+    }
+
+    public void setUpdateRect(Rectangle updateRect) {
+        this.updateRect = updateRect;
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * PaintEvent e = new PaintEvent(new Component(){}, 
+         *          PaintEvent.PAINT, new Rectangle(0, 0, 10, 20)); 
+         * System.out.println(e);
+         */
+
+        String typeString = null;
+
+        switch (id) {
+        case PAINT:
+            typeString = "PAINT"; //$NON-NLS-1$
+            break;
+        case UPDATE:
+            typeString = "UPDATE"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        return typeString + ",updateRect=" + updateRect; //$NON-NLS-1$
+    }
+
+}
diff --git a/awt/java/awt/event/TextEvent.java b/awt/java/awt/event/TextEvent.java
new file mode 100644
index 0000000..e2bfd96
--- /dev/null
+++ b/awt/java/awt/event/TextEvent.java
@@ -0,0 +1,53 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.awt.AWTEvent;
+
+public class TextEvent extends AWTEvent {
+
+    private static final long serialVersionUID = 6269902291250941179L;
+
+    public static final int TEXT_FIRST = 900;
+
+    public static final int TEXT_LAST = 900;
+
+    public static final int TEXT_VALUE_CHANGED = 900;
+
+    public TextEvent(Object src, int id) {
+        super(src, id);
+    }
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * TextEvent e = new TextEvent(new Component(){}, 
+         *          TextEvent.TEXT_VALUE_CHANGED); 
+         * System.out.println(e);
+         */
+
+        return (id == TEXT_VALUE_CHANGED) ? 
+                "TEXT_VALUE_CHANGED" : "unknown type"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+}
diff --git a/awt/java/awt/event/TextListener.java b/awt/java/awt/event/TextListener.java
new file mode 100644
index 0000000..6c5a671
--- /dev/null
+++ b/awt/java/awt/event/TextListener.java
@@ -0,0 +1,30 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface TextListener extends EventListener {
+
+    public void textValueChanged(TextEvent e);
+
+}
+
diff --git a/awt/java/awt/event/WindowAdapter.java b/awt/java/awt/event/WindowAdapter.java
new file mode 100644
index 0000000..9d4b377
--- /dev/null
+++ b/awt/java/awt/event/WindowAdapter.java
@@ -0,0 +1,58 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+public abstract class WindowAdapter implements WindowListener, WindowStateListener, WindowFocusListener {
+
+    public WindowAdapter() {
+    }
+
+    public void windowActivated(WindowEvent e) {
+    }
+
+    public void windowClosed(WindowEvent e) {
+    }
+
+    public void windowClosing(WindowEvent e) {
+    }
+
+    public void windowDeactivated(WindowEvent e) {
+    }
+
+    public void windowDeiconified(WindowEvent e) {
+    }
+
+    public void windowGainedFocus(WindowEvent e) {
+    }
+
+    public void windowIconified(WindowEvent e) {
+    }
+
+    public void windowLostFocus(WindowEvent e) {
+    }
+
+    public void windowOpened(WindowEvent e) {
+    }
+
+    public void windowStateChanged(WindowEvent e) {
+    }
+
+}
diff --git a/awt/java/awt/event/WindowEvent.java b/awt/java/awt/event/WindowEvent.java
new file mode 100644
index 0000000..65a30e4
--- /dev/null
+++ b/awt/java/awt/event/WindowEvent.java
@@ -0,0 +1,162 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+
+//???AWT
+//import java.awt.Window;
+//import java.awt.Frame;
+
+public class WindowEvent extends ComponentEvent {
+
+    private static final long serialVersionUID = -1567959133147912127L;
+
+    public static final int WINDOW_FIRST = 200;
+
+    public static final int WINDOW_OPENED = 200;
+
+    public static final int WINDOW_CLOSING = 201;
+
+    public static final int WINDOW_CLOSED = 202;
+
+    public static final int WINDOW_ICONIFIED = 203;
+
+    public static final int WINDOW_DEICONIFIED = 204;
+
+    public static final int WINDOW_ACTIVATED = 205;
+
+    public static final int WINDOW_DEACTIVATED = 206;
+
+    public static final int WINDOW_GAINED_FOCUS = 207;
+
+    public static final int WINDOW_LOST_FOCUS = 208;
+
+    public static final int WINDOW_STATE_CHANGED = 209;
+
+    public static final int WINDOW_LAST = 209;
+
+    //???AWT: private Window oppositeWindow;
+    private int oldState;
+    private int newState;
+
+    //???AWT
+    /*
+    public WindowEvent(Window source, int id) {
+        this(source, id, null);
+    }
+
+    public WindowEvent(Window source, int id, Window opposite) {
+        this(source, id, opposite, Frame.NORMAL, Frame.NORMAL);
+    }
+
+    public WindowEvent(Window source, int id, int oldState, int newState) {
+        this(source, id, null, oldState, newState);
+    }
+
+    public WindowEvent(Window source, int id, Window opposite, 
+                       int oldState, int newState) {
+        super(source, id);
+
+        oppositeWindow = opposite;
+        this.oldState = oldState;
+        this.newState = newState;
+    }
+    */
+    //???AWT: Fake constructor
+    public WindowEvent() {
+        super(null, 0);
+    }
+    
+    public int getNewState() {
+        return newState;
+    }
+
+    public int getOldState() {
+        return oldState;
+    }
+
+    //???AWT
+    /*
+    public Window getOppositeWindow() {
+        return oppositeWindow;
+    }
+
+    public Window getWindow() {
+        return (Window) source;
+    }
+    */
+
+    @Override
+    public String paramString() {
+        /* The format is based on 1.5 release behavior 
+         * which can be revealed by the following code:
+         * 
+         * WindowEvent e = new WindowEvent(new Frame(), 
+         *          WindowEvent.WINDOW_OPENED); 
+         * System.out.println(e);
+         */
+
+        String typeString = null;
+
+        switch (id) {
+        case WINDOW_OPENED:
+            typeString = "WINDOW_OPENED"; //$NON-NLS-1$
+            break;
+        case WINDOW_CLOSING:
+            typeString = "WINDOW_CLOSING"; //$NON-NLS-1$
+            break;
+        case WINDOW_CLOSED:
+            typeString = "WINDOW_CLOSED"; //$NON-NLS-1$
+            break;
+        case WINDOW_ICONIFIED:
+            typeString = "WINDOW_ICONIFIED"; //$NON-NLS-1$
+            break;
+        case WINDOW_DEICONIFIED:
+            typeString = "WINDOW_DEICONIFIED"; //$NON-NLS-1$
+            break;
+        case WINDOW_ACTIVATED:
+            typeString = "WINDOW_ACTIVATED"; //$NON-NLS-1$
+            break;
+        case WINDOW_DEACTIVATED:
+            typeString = "WINDOW_DEACTIVATED"; //$NON-NLS-1$
+            break;
+        case WINDOW_GAINED_FOCUS:
+            typeString = "WINDOW_GAINED_FOCUS"; //$NON-NLS-1$
+            break;
+        case WINDOW_LOST_FOCUS:
+            typeString = "WINDOW_LOST_FOCUS"; //$NON-NLS-1$
+            break;
+        case WINDOW_STATE_CHANGED:
+            typeString = "WINDOW_STATE_CHANGED"; //$NON-NLS-1$
+            break;
+        default:
+            typeString = "unknown type"; //$NON-NLS-1$
+        }
+
+        //???AWT
+        /*
+        return typeString + ",opposite=" + oppositeWindow + //$NON-NLS-1$
+                ",oldState=" + oldState + ",newState=" + newState; //$NON-NLS-1$ //$NON-NLS-2$
+        */
+        return typeString;
+    }
+
+}
diff --git a/awt/java/awt/event/WindowFocusListener.java b/awt/java/awt/event/WindowFocusListener.java
new file mode 100644
index 0000000..e0200f2
--- /dev/null
+++ b/awt/java/awt/event/WindowFocusListener.java
@@ -0,0 +1,31 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface WindowFocusListener extends EventListener {
+
+    public void windowGainedFocus(WindowEvent e);
+
+    public void windowLostFocus(WindowEvent e);
+
+}
diff --git a/awt/java/awt/event/WindowListener.java b/awt/java/awt/event/WindowListener.java
new file mode 100644
index 0000000..20a2b08
--- /dev/null
+++ b/awt/java/awt/event/WindowListener.java
@@ -0,0 +1,41 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface WindowListener extends EventListener {
+
+    public void windowActivated(WindowEvent e);
+
+    public void windowClosed(WindowEvent e);
+
+    public void windowClosing(WindowEvent e);
+
+    public void windowDeactivated(WindowEvent e);
+
+    public void windowDeiconified(WindowEvent e);
+
+    public void windowIconified(WindowEvent e);
+
+    public void windowOpened(WindowEvent e);
+
+}
diff --git a/awt/java/awt/event/WindowStateListener.java b/awt/java/awt/event/WindowStateListener.java
new file mode 100644
index 0000000..12dbc20
--- /dev/null
+++ b/awt/java/awt/event/WindowStateListener.java
@@ -0,0 +1,30 @@
+/*
+ *  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 Michael Danilov
+ * @version $Revision$
+ */
+package java.awt.event;
+
+import java.util.EventListener;
+
+public interface WindowStateListener extends EventListener {
+
+    public void windowStateChanged(WindowEvent e);
+
+}
+
diff --git a/awt/java/awt/font/FontRenderContext.java b/awt/java/awt/font/FontRenderContext.java
new file mode 100644
index 0000000..766300d
--- /dev/null
+++ b/awt/java/awt/font/FontRenderContext.java
@@ -0,0 +1,168 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+
+/**
+ * The FontRenderContext class contains the information 
+ * about text measurement. Anti-aliasing and fractional-metrics
+ * modes are defined by an application and affect the size of
+ * a character.
+ */
+public class FontRenderContext {
+
+    // Affine transform of this mode
+    /** The transform. */
+    private AffineTransform transform;
+
+    // Is the anti-aliased mode used
+    /** The anti aliased. */
+    private boolean fAntiAliased;
+
+    // Is the fractional metrics used
+    /** The fractional metrics. */
+    private boolean fFractionalMetrics;
+
+
+    /**
+     * Instantiates a new FontRenderContext object with the specified
+     * AffineTransform, anti-aliasing and fractional metrics flags.
+     * 
+     * @param trans the AffineTransform.
+     * @param antiAliased the anti-aliasing flag.
+     * @param usesFractionalMetrics the fractional metrics flag.
+     */
+    public FontRenderContext(AffineTransform trans, boolean antiAliased, 
+            boolean usesFractionalMetrics) {
+        if (trans != null){
+            transform = new AffineTransform(trans);
+        }
+        fAntiAliased = antiAliased;
+        fFractionalMetrics = usesFractionalMetrics;
+    }
+
+    /**
+     * Instantiates a new FontRenderContext object.
+     */
+    protected FontRenderContext() {
+    }
+
+    /**
+     * Compares the specified Object with current FontRenderContext object. 
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is equal to current
+     * FontRenderContext object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj != null) {
+            try {
+                return equals((FontRenderContext) obj);
+            } catch (ClassCastException e) {
+                return false;
+            }
+        }
+        return false;
+
+    }
+
+    /**
+     * Gets the transform which is used for scaling typographical points 
+     * to pixels in this FontRenderContext.
+     * 
+     * @return the AffineTransform which is used for scaling typographical 
+     * points to pixels in this FontRenderContext.
+     */
+    public AffineTransform getTransform() {
+        if (transform != null){
+            return new AffineTransform(transform);
+        }
+        return new AffineTransform();
+    }
+
+    /**
+     * Compares the specified FontRenderContext object with current 
+     * FontRenderContext.
+     * 
+     * @param frc the FontRenderContext object to be compared.
+     * 
+     * @return true, if the specified FontRenderContext object is
+     * equal to current FontRenderContext.
+     */
+    public boolean equals(FontRenderContext frc) {
+        if (this == frc){
+            return true;
+        }
+
+        if (frc == null){
+            return false;
+        }
+
+        if (!frc.getTransform().equals(this.getTransform()) &&
+            !frc.isAntiAliased() == this.fAntiAliased &&
+            !frc.usesFractionalMetrics() == this.fFractionalMetrics){
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the text fractional metrics are used in 
+     * this FontRenderContext.
+     * 
+     * @return true, if the text fractional metrics are used in 
+     * this FontRenderContext, false otherwise.
+     */
+    public boolean usesFractionalMetrics() {
+        return this.fFractionalMetrics;
+    }
+
+    /**
+     * Returns true if anti-aliasing is used in this FontRenderContext.
+     * 
+     * @return true, if is anti-aliasing is used in this FontRenderContext,
+     * false otherwise.
+     */
+    public boolean isAntiAliased() {
+        return this.fAntiAliased;
+    }
+
+    /**
+     * Returns hash code of the FontRenderContext object.
+     * 
+     * @return the hash code of the FontRenderContext object.
+     */
+    @Override
+    public int hashCode() {
+        return this.getTransform().hashCode() ^
+                new Boolean(this.fFractionalMetrics).hashCode() ^
+                new Boolean(this.fAntiAliased).hashCode();
+    }
+
+}
+
diff --git a/awt/java/awt/font/GlyphJustificationInfo.java b/awt/java/awt/font/GlyphJustificationInfo.java
new file mode 100644
index 0000000..4c3e02e
--- /dev/null
+++ b/awt/java/awt/font/GlyphJustificationInfo.java
@@ -0,0 +1,185 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GlyphJustificationInfo class provides information about 
+ * the glyph's justification properties. There are four justification 
+ * properties: weight, priority, absorb, and limit.
+ * <p>
+ * There are two sets of metrics: growing and shrinking. 
+ * Growing metrics are used when the glyphs are to be spread apart 
+ * to fit a larger width. Shrinking metrics are used when the glyphs 
+ * are to be moved together to fit a smaller width.
+ */
+public final class GlyphJustificationInfo {
+
+    /** 
+     * The Constant PRIORITY_KASHIDA indicates the highest 
+     * justification priority.
+     */
+    public static final int PRIORITY_KASHIDA = 0;
+
+    /**
+     * The Constant PRIORITY_WHITESPACE indicates the second highest 
+     * justification priority. 
+     */
+    public static final int PRIORITY_WHITESPACE = 1;
+
+    /** 
+     * The Constant PRIORITY_INTERCHAR indicates the second lowest 
+     * justification priority. 
+     */
+    public static final int PRIORITY_INTERCHAR = 2;
+
+    /**
+     * The Constant PRIORITY_NONE indicates the lowest justification 
+     * priority.
+     */
+    public static final int PRIORITY_NONE = 3;
+
+    /** 
+     * The grow absorb flag indicates if this glyph absorbs all extra 
+     * space at this and lower priority levels when it grows.
+     */
+    public final boolean growAbsorb;
+
+    /** 
+     * The grow left limit value represents the maximum value by which 
+     * the left side of this glyph grows. 
+     */
+    public final float growLeftLimit;
+
+    /** 
+     * The grow right limit value repesents the maximum value by which 
+     * the right side of this glyph grows.
+     */
+    public final float growRightLimit;
+
+    /** 
+     * The grow priority value represents the priority level of this 
+     * glyph as it is growing. 
+     */
+    public final int growPriority;
+
+    /** 
+     * The shrink absorb fleg indicates this glyph absorbs all remaining 
+     * shrinkage at this and lower priority levels as it shrinks. 
+     */
+    public final boolean shrinkAbsorb;
+
+    /** 
+     * The shrink left limit value represents the maximum value by which 
+     * the left side of this glyph shrinks. 
+     */
+    public final float shrinkLeftLimit;
+
+    /** 
+     * The shrink right limit value represents the maximum value by which 
+     * the right side of this glyph shrinks. 
+     */
+    public final float shrinkRightLimit;
+
+    /**
+     * The shrink priority represents the glyth's priority level 
+     * as it is shrinking.
+     */
+    public final int shrinkPriority;
+
+    /** 
+     * The weight of the glyph. 
+     */
+    public final float weight;
+
+    /**
+     * Instantiates a new GlyphJustificationInfo object which contains
+     * glyph's justification properties.
+     * 
+     * @param weight the weight of glyph.
+     * @param growAbsorb indicates if this glyph contais all space 
+     * at this priority and lower priority levels when it grows.
+     * @param growPriority indicates the priority level of this glyph 
+     * when it grows.
+     * @param growLeftLimit indicates the maximum value of which the 
+     * left side of this glyph can grow.
+     * @param growRightLimit the maximum value of which the right side of 
+     * this glyph can grow.
+     * @param shrinkAbsorb indicates if this glyph contains all remaining
+     * shrinkage at this and lower priority levels when it shrinks.
+     * @param shrinkPriority indicates the glyph's priority level when 
+     * it shrinks.
+     * @param shrinkLeftLimit indicates the maximum value of which 
+     * the left side of this glyph can shrink. 
+     * @param shrinkRightLimit indicates the maximum amount by which 
+     * the right side of this glyph can shrink.
+     */
+    public GlyphJustificationInfo(float weight, boolean growAbsorb, int growPriority,
+            float growLeftLimit, float growRightLimit, boolean shrinkAbsorb,
+            int shrinkPriority, float shrinkLeftLimit, float shrinkRightLimit) {
+
+        if (weight < 0) {
+            // awt.19C=weight must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19C")); //$NON-NLS-1$
+        }
+        this.weight = weight;
+
+        if (growLeftLimit < 0) {
+            // awt.19D=growLeftLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19D")); //$NON-NLS-1$
+        }
+        this.growLeftLimit = growLeftLimit;
+
+        if (growRightLimit < 0) {
+            // awt.19E=growRightLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.19E")); //$NON-NLS-1$
+        }
+        this.growRightLimit = growRightLimit;
+
+        if ((shrinkPriority < 0) || (shrinkPriority > PRIORITY_NONE)) {
+            // awt.19F=incorrect value for shrinkPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
+            throw new IllegalArgumentException(Messages.getString("awt.19F")); //$NON-NLS-1$
+        }
+        this.shrinkPriority = shrinkPriority;
+
+        if ((growPriority < 0) || (growPriority > PRIORITY_NONE)) {
+            // awt.200=incorrect value for growPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
+            throw new IllegalArgumentException(Messages.getString("awt.200")); //$NON-NLS-1$
+        }
+        this.growPriority = growPriority;
+
+        if (shrinkLeftLimit < 0) {
+            // awt.201=shrinkLeftLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.201")); //$NON-NLS-1$
+        }
+        this.shrinkLeftLimit = shrinkLeftLimit;
+
+        if (shrinkRightLimit < 0) {
+            // awt.202=shrinkRightLimit must be a positive number
+            throw new IllegalArgumentException(Messages.getString("awt.202")); //$NON-NLS-1$
+        }
+        this.shrinkRightLimit = shrinkRightLimit;
+
+        this.shrinkAbsorb = shrinkAbsorb;
+        this.growAbsorb = growAbsorb;
+    }
+}
diff --git a/awt/java/awt/font/GlyphMetrics.java b/awt/java/awt/font/GlyphMetrics.java
new file mode 100644
index 0000000..d96ef18
--- /dev/null
+++ b/awt/java/awt/font/GlyphMetrics.java
@@ -0,0 +1,248 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The GlyphMetrics class provides information about the size and shape 
+ * of a single glyph. 
+ * Each glyph has information to specify whether its baseline is horizontal 
+ * or vertical as well as information on how it interacts with 
+ * other characters in a text, given as one of the
+ * following types: STANDARD, LIGATURE, COMBINING, or COMPONENT.
+ */
+public final class GlyphMetrics {
+
+    // advance width of the glyph character cell
+    /** The advance x. */
+    private float advanceX;
+    
+    // advance height of the glyph character cell
+    /** The advance y. */
+    private float advanceY;
+
+    // flag if the glyph horizontal
+    /** The horizontal. */
+    private boolean horizontal;
+
+    // glyph type code 
+    /** The glyph type. */
+    private byte glyphType;
+    
+    // bounding box for outline of the glyph
+    /** The bounds. */
+    private Rectangle2D.Float bounds;
+
+    /** 
+     * The Constant STANDARD indicates a glyph that represents a single 
+     * character. 
+     */
+    public static final byte STANDARD = 0;
+
+    /** 
+     * The Constant LIGATURE indicates a glyph that represents multiple 
+     * characters as a ligature. 
+     */
+    public static final byte LIGATURE = 1;
+
+    /** 
+     * The Constant COMBINING indicates a glyph which has no caret position 
+     * between glyphs (for example umlaut).
+     */
+    public static final byte COMBINING = 2;
+
+    /** 
+     * The Constant COMPONENT indicates a glyph with no corresponding character 
+     * in the backing store.
+     */
+    public static final byte COMPONENT = 3;
+
+    /** 
+     * The Constant WHITESPACE indicates a glyph without visual 
+     * representation. 
+     */
+    public static final byte WHITESPACE = 4;
+
+    /**
+     * Instantiates a new GlyphMetrics object with the specified parameters.
+     * 
+     * @param horizontal specifies if metrics are for a horizontal baseline 
+     * (true value), or a vertical baseline (false value).
+     * @param advanceX the X component of the glyph's advance.
+     * @param advanceY the Y component of the glyph's advance.
+     * @param bounds the glyph's bounds.
+     * @param glyphType the glyph's type.
+     */
+    public GlyphMetrics(boolean horizontal, float advanceX, float advanceY, 
+            Rectangle2D bounds, byte glyphType) {
+        this.horizontal = horizontal;
+        this.advanceX = advanceX;
+        this.advanceY = advanceY;
+
+        this.bounds = new Rectangle2D.Float();
+        this.bounds.setRect(bounds);
+
+        this.glyphType = glyphType;
+    }
+
+    /**
+     * Instantiates a new horizontal GlyphMetrics with the specified parameters.
+     * 
+     * @param advanceX the X component of the glyph's advance.
+     * @param bounds the glyph's bounds.
+     * @param glyphType the glyph's type.
+     */
+    public GlyphMetrics(float advanceX, Rectangle2D bounds, byte glyphType) {
+        this.advanceX = advanceX;
+        this.advanceY = 0;
+
+        this.horizontal = true;
+
+        this.bounds = new Rectangle2D.Float();
+        this.bounds.setRect(bounds);
+
+        this.glyphType = glyphType;
+    }
+
+    /**
+     * Gets the glyph's bounds.
+     * 
+     * @return glyph's bounds.
+     */
+    public Rectangle2D getBounds2D() {
+        return (Rectangle2D.Float) this.bounds.clone();
+    }
+
+    /**
+     * Checks if this glyph is whitespace or not.
+     * 
+     * @return true, if this glyph is whitespace, false otherwise.
+     */
+    public boolean isWhitespace() {
+        return ((this.glyphType & 4) == WHITESPACE);
+    }
+
+    /**
+     * Checks if this glyph is standard or not.
+     * 
+     * @return true, if this glyph is standard, false otherwise.
+     */
+    public boolean isStandard() {
+        return ((this.glyphType & 3) == STANDARD);
+    }
+
+    /**
+     * Checks if this glyph is ligature or not.
+     * 
+     * @return true, if this glyph is ligature, false otherwise.
+     */
+    public boolean isLigature() {
+        return ((this.glyphType & 3) == LIGATURE);
+    }
+
+    /**
+     * Checks if this glyph is component or not.
+     * 
+     * @return true, if this glyph is component, false otherwise.
+     */
+    public boolean isComponent() {
+        return ((this.glyphType & 3) == COMPONENT);
+    }
+
+    /**
+     * Checks if this glyph is combining or not.
+     * 
+     * @return true, if this glyph is combining, false otherwise.
+     */
+    public boolean isCombining() {
+        return ((this.glyphType & 3) == COMBINING);
+    }
+
+    /**
+     * Gets the glyph's type.
+     * 
+     * @return the glyph's type.
+     */
+    public int getType() {
+        return this.glyphType;
+    }
+
+    /**
+     * Gets the distance from the right (for horizontal) or 
+     * bottom (for vertical) of the glyph bounds to the advance.
+     * 
+     * @return the distance from the right (for horizontal) or 
+     * bottom (for vertical) of the glyph bounds to the advance.
+     */
+    public float getRSB() {
+        if (this.horizontal) {
+            return this.advanceX - this.bounds.x - (float)this.bounds.getWidth();
+        }
+        return this.advanceY - this.bounds.y - (float)this.bounds.getHeight();
+    }
+
+    /**
+     * Gets the distance from 0, 0 to the left (for horizontal) 
+     * or top (for vertical) of the glyph bounds.
+     * 
+     * @return the distance from 0, 0 to the left (for horizontal) 
+     * or top (for vertical) of the glyph bounds.
+     */
+    public float getLSB() {
+        if (this.horizontal) {
+            return this.bounds.x;
+        }
+        return this.bounds.y;
+    }
+
+    /**
+     * Gets the Y component of the glyph's advance.
+     * 
+     * @return the Y component of the glyph's advance.
+     */
+    public float getAdvanceY() {
+        return this.advanceY;
+    }
+
+    /**
+     * Gets the X component of the glyph's advance.
+     * 
+     * @return the X component of the glyph's advance.
+     */
+    public float getAdvanceX() {
+        return this.advanceX;
+    }
+
+    /**
+     * Gets the glyph's advance along the baseline.
+     * 
+     * @return the glyph's advance.
+     */
+    public float getAdvance() {
+        if (this.horizontal) {
+            return this.advanceX;
+        }
+        return this.advanceY;
+    }
+
+}
+
diff --git a/awt/java/awt/font/GlyphVector.java b/awt/java/awt/font/GlyphVector.java
new file mode 100644
index 0000000..b3c9406
--- /dev/null
+++ b/awt/java/awt/font/GlyphVector.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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Font;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The GlyphVector class contains a collection of glyphs with geometric 
+ * information and each glyph's location. Each GlyphVector can be associated 
+ * with only one Font. GlyphVector contains the following properties for 
+ * each glyph:
+ * <ul>
+ * <li>the glyph position;</li>
+ * <li>the transform of the glyph;</li>
+ * <li>the metrics of the glyph in the context of the GlyphVector.</li>
+ * </ul>
+ */
+public abstract class GlyphVector implements Cloneable {
+
+    /** 
+     * The Constant FLAG_HAS_TRANSFORMS indicates that this GlyphVector 
+     * has per-glyph transforms.
+     */
+    public static final int FLAG_HAS_TRANSFORMS = 1;
+
+    /** 
+     * The Constant FLAG_HAS_POSITION_ADJUSTMENTS indicates that 
+     * the GlyphVector has per-glyph position adjustments. 
+     */
+    public static final int FLAG_HAS_POSITION_ADJUSTMENTS = 2;
+
+    /** 
+     * The Constant FLAG_RUN_RTL indicates that this GlyphVector has a 
+     * right to left run direction.
+     */
+    public static final int FLAG_RUN_RTL = 4;
+
+    /** 
+     * The Constant FLAG_COMPLEX_GLYPHS indicates that this GlyphVector 
+     * has a complex glyph to char mapping.
+     */
+    public static final int FLAG_COMPLEX_GLYPHS = 8;
+
+    /** 
+     * The Constant FLAG_MASK indicates a mask for supported flags 
+     * from getLayoutFlags.
+     */
+    public static final int FLAG_MASK = 15; // (|) mask of other flags
+
+    /**
+     * Instantiates a new GlyphVector.
+     */
+    public GlyphVector() {
+    }
+
+    /**
+     * Gets the pixel bounds of the GlyphVector when rendered
+     * at the specified location with the specified FontRenderContext.
+     * 
+     * @param frc the FontRenderContext.
+     * @param x the X coordinate of the GlyphVector's location.
+     * @param y the Y coordinate of the GlyphVector's location.
+     * 
+     * @return the pixel bounds
+     */
+    public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
+        // default implementation - integer Rectangle, that encloses visual 
+        // bounds rectangle
+        Rectangle2D visualRect = getVisualBounds();
+
+        int minX = (int)Math.floor(visualRect.getMinX() + x);
+        int minY = (int)Math.floor(visualRect.getMinY() + y);
+        int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
+        int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
+
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the pixel bounds of the glyph with the specified index in
+     * this GlyphVector which is rendered with the specified
+     * FontRenderContext at the specified location.
+     * 
+     * @param index the glyph index in this GlyphVector.
+     * @param frc the FontRenderContext.
+     * @param x the X coordinate of the GlyphVector's location.
+     * @param y the Y coordinate of the GlyphVector's location.
+     * 
+     * @return a Rectangle bounds.
+     */
+    public Rectangle getGlyphPixelBounds(int index, FontRenderContext frc, 
+            float x, float y) {
+        Rectangle2D visualRect = getGlyphVisualBounds(index).getBounds2D();
+
+        int minX = (int)Math.floor(visualRect.getMinX() + x);
+        int minY = (int)Math.floor(visualRect.getMinY() + y);
+        int width = (int)Math.ceil(visualRect.getMaxX() + x) - minX;
+        int height = (int)Math.ceil(visualRect.getMaxY() + y) - minY;
+
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the visual bounds of the GlyphVector. 
+     * 
+     * @return the visual bounds of the GlyphVector.
+     */
+    public abstract Rectangle2D getVisualBounds();
+
+    /**
+     * Gets the logical bounds of the GlyphVector. 
+     * 
+     * @return the logical bounds of the GlyphVector.
+     */
+    public abstract Rectangle2D getLogicalBounds();
+
+    /**
+     * Sets the position of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * @param newPos the new position of the glyph at the specified glyphIndex.
+     */
+    public abstract void setGlyphPosition(int glyphIndex, Point2D newPos);
+
+    /**
+     * Gets the position of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * 
+     * @return the position of the specified glyph in this GlyphVector.
+     */
+    public abstract Point2D getGlyphPosition(int glyphIndex);
+
+    /**
+     * Sets the affine transform to a glyph with the specified index
+     * in this GlyphVector.
+     * 
+     * @param glyphIndex the glyth index in this GlyphVector.
+     * @param trans the AffineTransform to be assigned to the
+     * specified glyph.
+     */
+    public abstract void setGlyphTransform(int glyphIndex, 
+            AffineTransform trans);
+
+    /**
+     * Gets the transform of the specified glyph in this GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * 
+     * @return the new transform of the glyph.
+     */
+    public abstract AffineTransform getGlyphTransform(int glyphIndex);
+
+    /**
+     * Compares this GlyphVector with the specified GlyphVector objects.
+     * 
+     * @param glyphVector the GlyphVector object to be compared.
+     * 
+     * @return true, if this GlyphVector is equal to the specified GlyphVector
+     * object, false otherwise.
+     */
+    public abstract boolean equals(GlyphVector glyphVector);
+
+    /**
+     * Gets the metrics of the glyph with the specified index
+     * in this GlyphVector.
+     * 
+     * @param glyphIndex index in this GlyphVector.
+     * 
+     * @return the metrics of the glyph with the specified index
+     * in this GlyphVector.
+     */
+    public abstract GlyphMetrics getGlyphMetrics(int glyphIndex);
+
+    /**
+     * Gets the justification information of the glyph 
+     * whose index is specified.
+     * 
+     * @param glyphIndex the glyph index.
+     * 
+     * @return the GlyphJustificationInfo for the specified glyph. 
+     */
+    public abstract GlyphJustificationInfo getGlyphJustificationInfo(
+            int glyphIndex);
+
+    /**
+     * Gets the FontRenderContext of this GlyphVector.
+     * 
+     * @return the FontRenderContext of this GlyphVector.
+     */
+    public abstract FontRenderContext getFontRenderContext();
+
+    /**
+     * Gets a Shape object which defines the visual representation 
+     * of the specified glyph in this GlyphVector, translated a 
+     * distance of x in the X direction and y in the Y direction. 
+     * 
+     * @param glyphIndex the glyth index in this GlyphVector.
+     * @param x the distance in the X direction to translate the 
+     * shape object before returning it.
+     * @param y the distance in the Y direction to translate the 
+     * shape object before returning it.
+     * 
+     * @return a Shape object which represents the visual representation 
+     * of the specified glyph in this GlyphVector - glyph outline. 
+     */
+    public Shape getGlyphOutline(int glyphIndex, float x, float y) {
+        Shape initialShape = getGlyphOutline(glyphIndex);
+        AffineTransform trans = AffineTransform.getTranslateInstance(x, y);
+        return trans.createTransformedShape(initialShape);
+    }
+
+    /**
+     * Gets the visual bounds of the specified glyph in the GlyphVector.
+     * 
+     * @param glyphIndex the glyph index in this GlyphVector.
+     * 
+     * @return the glyph visual bounds of the glyph with the specified
+     * index in the GlyphVector.
+     */
+    public abstract Shape getGlyphVisualBounds(int glyphIndex);
+
+    /**
+     * Gets a Shape object which defines the visual representation 
+     * of the specified glyph in this GlyphVector. 
+     *  
+     * @param glyphIndex the glyth index in this GlyphVector.
+     * 
+     * @return a Shape object which represents the visual representation 
+     * of the specified glyph in this GlyphVector - glyph outline. 
+     */
+    public abstract Shape getGlyphOutline(int glyphIndex);
+
+    /**
+     * Gets the logical bounds of the specified glyph in 
+     * the GlyphVector. 
+     * 
+     * @param glyphIndex the index in this GlyphVector of the glyph from which 
+     * to retrieve its logical bounds
+     * 
+     * @return the logical bounds of the specified glyph in 
+     * the GlyphVector.
+     */
+    public abstract Shape getGlyphLogicalBounds(int glyphIndex);
+
+    /**
+     * Gets the visual representation of this GlyphVector rendered in
+     * x, y location as a Shape object.
+     * 
+     * @param x the x coordinate of the GlyphVector.
+     * @param y the y coordinate of the GlyphVector.
+     * 
+     * @return the visual representation of this GlyphVector as a Shape object.
+     */
+    public abstract Shape getOutline(float x, float y);
+
+    /**
+     * Gets the visual representation of this GlyphVector as a Shape object.
+     * 
+     * @return the visual representation of this GlyphVector as a Shape object.
+     */
+    public abstract Shape getOutline();
+
+    /**
+     * Gets the font of this GlyphVector.
+     * 
+     * @return the font of this GlyphVector.
+     */
+    public abstract Font getFont();
+
+    /**
+     * Gets an array of the glyph codes of the specified glyphs.
+     * 
+     * @param beginGlyphIndex the index into this GlyphVector at which 
+     * to start retrieving glyph codes.
+     * @param numEntries the number of glyph codes.
+     * @param codeReturn the array into which the resulting 
+     * glyphcodes will be written.
+     * 
+     * @return the array of the glyph codes.
+     */
+    public abstract int[] getGlyphCodes(int beginGlyphIndex, int numEntries, 
+            int[] codeReturn);
+
+    /**
+     * Gets an array of the character indices of 
+     * the specified glyphs.
+     * 
+     * @param beginGlyphIndex the index of the first glyph to return information for.
+     * @param numEntries the number of glyph indices to return.
+     * @param codeReturn the array into which the resulting character 
+     * indices will be written.
+     * 
+     * @return an array of character indices for the specifies glyphs.
+     */
+    public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries, 
+            int[] codeReturn) {
+        if (codeReturn == null) {
+            codeReturn = new int[numEntries];
+        }
+
+        for (int i = 0; i < numEntries; i++){
+            codeReturn[i] = getGlyphCharIndex(i+beginGlyphIndex);
+        }
+        return codeReturn;
+    }
+
+    /**
+     * Gets an array of the positions of the specified glyphs in 
+     * this GlyphVector.
+     * 
+     * @param beginGlyphIndex the index of the first glyph to return information for.
+     * @param numEntries the number of glyphs to return information for.
+     * @param positionReturn the array where the result will be stored. 
+     * 
+     * @return an array of glyph positions.
+     */
+    public abstract float[] getGlyphPositions(int beginGlyphIndex, 
+            int numEntries, float[] positionReturn);
+
+    /**
+     * Gets the glyph code of the specified glyph.
+     * 
+     * @param glyphIndex the index in this GlyphVector which corresponds 
+     * to the glyph from which to retrieve the glyphcode.
+     * 
+     * @return the glyphcode of the specified glyph.
+     */
+    public abstract int getGlyphCode(int glyphIndex);
+
+    /**
+     * Gets the first logical character's index of the specified glyph. 
+     *  
+     * @param glyphIndex the glyph index.
+     * 
+     * @return the the first logical character's index.
+     */
+    public int getGlyphCharIndex(int glyphIndex){
+        // default implemetation one-to-one
+        return glyphIndex;
+    }
+
+    /**
+     * Sets default layout to this GlyphVector. 
+     */
+    public abstract void performDefaultLayout();
+
+    /**
+     * Gets the number of glyphs in the GlyphVector.
+     * 
+     * @return the number of glyphs in the GlyphVector.
+     */
+    public abstract int getNumGlyphs();
+
+    /**
+     * Gets flags which describe the global state of the GlyphVector. 
+     * The default implementation returns 0.
+     * 
+     * @return the layout flags
+     */
+    public int getLayoutFlags(){
+        // default implementation - returned value is 0
+        return 0;
+    }
+
+}
+
diff --git a/awt/java/awt/font/GraphicAttribute.java b/awt/java/awt/font/GraphicAttribute.java
new file mode 100644
index 0000000..2f41951
--- /dev/null
+++ b/awt/java/awt/font/GraphicAttribute.java
@@ -0,0 +1,196 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The GraphicAttribute abstract class provides an opportunity to
+ * insert graphical elements in printed text.   
+ */
+public abstract class GraphicAttribute {
+
+    /** 
+     * The Constant TOP_ALIGNMENT indicates using the top line to 
+     * calculate placement of graphics.
+     */
+    public static final int TOP_ALIGNMENT = -1;
+
+    /** 
+     * The Constant BOTTOM_ALIGNMENT indicates using the bottom line to 
+     * calculate placement of graphics. 
+     */
+    public static final int BOTTOM_ALIGNMENT = -2;
+
+    /** 
+     * The Constant ROMAN_BASELINE indicates the placement of the roman 
+     * baseline with respect to the graphics origin.
+     */
+    public static final int ROMAN_BASELINE = 0;
+
+    /** 
+     * The Constant CENTER_BASELINE indicates the placement of the center 
+     * baseline with respect to the graphics origin.
+     */
+    public static final int CENTER_BASELINE = 1;
+
+    /** 
+     * The Constant HANGING_BASELINE indicates the placement of the hanging 
+     * baseline with respect to the graphics origin. 
+     */
+    public static final int HANGING_BASELINE = 2;
+
+    // the alignment of this GraphicAttribute
+    /** The alignment. */
+    private int alignment;
+
+    /**
+     * Instantiates a new graphic attribute with the specified alignment.
+     * 
+     * @param align the specified alignment.
+     */
+    protected GraphicAttribute(int align) {
+        if ((align < BOTTOM_ALIGNMENT) || (align > HANGING_BASELINE)) {
+            // awt.198=Illegal alignment argument
+            throw new IllegalArgumentException(Messages.getString("awt.198")); //$NON-NLS-1$
+        }
+        this.alignment = align;
+    }
+
+    /**
+     * Draws the GraphicAttribute at the specified location.
+     * 
+     * @param graphics the Graphics.
+     * @param x the X coordinate of GraphicAttribute location.
+     * @param y the Y coordinate of GraphicAttribute location.
+     */
+    public abstract void draw(Graphics2D graphics, float x, float y);
+
+    /**
+     * Gets the GraphicAttribute's advance. It's the distance from the point 
+     * at which the graphic is rendered and the point where the next character 
+     * or graphic is rendered.
+     * 
+     * @return the GraphicAttribute's advance.
+     */
+    public abstract float getAdvance();
+
+    /**
+     * Gets the alignment of this GraphicAttribute.
+     * 
+     * @return the alignment of this GraphicAttribute.
+     */
+    public final int getAlignment() {
+        return this.alignment;
+    }
+
+    /**
+     * Gets the ascent of this GraphicAttribute.
+     * 
+     * @return the ascent of this GraphicAttribute.
+     */
+    public abstract float getAscent();
+
+    /**
+     * Gets the bounds of this GraphicAttribute.
+     * 
+     * @return the bounds of this GraphicAttribute.
+     */
+    public Rectangle2D getBounds() {
+        float ascent = getAscent();
+        float advance = getAdvance();
+        float descent = getDescent();
+
+        // Default implementation - see API documentation.
+        return new Rectangle2D.Float(0, -ascent, advance, ascent + descent);
+    }
+
+    /**
+     * Gets the descent of this GraphicAttribute.
+     * 
+     * @return the descent of this GraphicAttribute.
+     */
+    public abstract float getDescent();
+
+    /**
+     * Gets the GlyphJustificationInfo of this GraphicAttribute.
+     * 
+     * @return the GlyphJustificationInfo of this GraphicAttribute.
+     */
+    public GlyphJustificationInfo getJustificationInfo() {
+        
+        /* Default implementation.
+         * Since documentation doesn't describe default values,
+         * they were calculated based on 1.5 release 
+         * behavior and can be obtained using next test sample:
+         * 
+         *    // Create GraphicAttribute class implementation
+         *    public class MyGraphicAttribute extends GraphicAttribute {
+         *        protected MyGraphicAttribute(int align) {
+         *            super(align);
+         *        }
+         *
+         *        public float getDescent() {
+         *           return 0;
+         *        }
+         *
+         *        public float getAdvance() {
+         *           return 1;
+         *        }
+         *
+         *        public void draw(Graphics2D g2, float x, float y) {
+         *        }
+         *
+         *        public float getAscent() {
+         *            return 0;
+         *        }
+         *    }
+         *
+         *    MyGraphicAttribute myGA = gat.new MyGraphicAttribute(0);
+         *    // print justification parameters
+         *    System.out.println(myGA.getJustificationInfo().growAbsorb);
+         *    System.out.println(myGA.getJustificationInfo().shrinkAbsorb);
+         *    System.out.println(myGA.getJustificationInfo().growLeftLimit);
+         *    System.out.println(myGA.getJustificationInfo().growPriority);
+         *    System.out.println(myGA.getJustificationInfo().growRightLimit);
+         *    System.out.println(myGA.getJustificationInfo().shrinkLeftLimit);
+         *    System.out.println(myGA.getJustificationInfo().shrinkPriority);
+         *    System.out.println(myGA.getJustificationInfo().shrinkRightLimit);
+         *    System.out.println(myGA.getJustificationInfo().weight);
+         */
+        float advance = getAdvance();
+        return new GlyphJustificationInfo(
+                                    advance,
+                                    false,
+                                    GlyphJustificationInfo.PRIORITY_INTERCHAR,
+                                    advance / 3,
+                                    advance / 3,
+                                    false,
+                                    GlyphJustificationInfo.PRIORITY_WHITESPACE,
+                                    0,
+                                    0);
+    }
+
+}
+
diff --git a/awt/java/awt/font/ImageGraphicAttribute.java b/awt/java/awt/font/ImageGraphicAttribute.java
new file mode 100644
index 0000000..41f90b8
--- /dev/null
+++ b/awt/java/awt/font/ImageGraphicAttribute.java
@@ -0,0 +1,179 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The ImageGraphicAttribute class provides an opportunity to insert 
+ * images to a text.
+ */
+public final class ImageGraphicAttribute extends GraphicAttribute {
+
+    // Image object rendered by this ImageGraphicAttribute
+    /** The image. */
+    private Image fImage;
+
+    // X coordinate of the origin point
+    /** The origin x. */
+    private float fOriginX;
+
+    // Y coordinate of the origin point
+    /** The origin y. */
+    private float fOriginY;
+
+    // the width of the image object
+    /** The img width. */
+    private float fImgWidth;
+
+    // the height of the image object
+    /** The img height. */
+    private float fImgHeight;
+
+    /**
+     * Instantiates a new ImageGraphicAttribute with the specified image,
+     * alignment and origins.
+     * 
+     * @param image the Image to be rendered by ImageGraphicAttribute.
+     * @param alignment the alignment of the ImageGraphicAttribute.
+     * @param originX the origin X coordinate in the image of
+     * ImageGraphicAttribute.  
+     * @param originY the origin Y coordinate in the image of
+     * ImageGraphicAttribute.  
+     */
+    public ImageGraphicAttribute(Image image, int alignment, float originX, 
+            float originY) {
+        super(alignment);
+
+        this.fImage = image;
+        this.fOriginX = originX;
+        this.fOriginY = originY;
+
+        this.fImgWidth = fImage.getWidth(null);
+        this.fImgHeight = fImage.getHeight(null);
+
+    }
+
+    /**
+     * Instantiates a new ImageGraphicAttribute with the specified image and
+     * alignment.
+     * 
+     * @param image the Image to be rendered by ImageGraphicAttribute.
+     * @param alignment the alignment of the ImageGraphicAttribute.
+     */
+    public ImageGraphicAttribute(Image image, int alignment) {
+        this(image, alignment, 0, 0);
+    }
+
+    /**
+     * Returns a hash code of this ImageGraphicAttribute object.
+     * 
+     * @return the hash code of this ImageGraphicAttribute object.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(fImage.hashCode());
+        hash.append(getAlignment());
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares the specified ImageGraphicAttribute object with this
+     * ImageGraphicAttribute object.
+     * 
+     * @param iga the ImageGraphicAttribute object to be compared.
+     * 
+     * @return true, if the specified ImageGraphicAttribute object is equal to
+     * this ImageGraphicAttribute object, false otherwise.
+     */
+    public boolean equals(ImageGraphicAttribute iga) {
+        if (iga == null) {
+            return false;
+        }
+
+        if (iga == this) {
+            return true;
+        }
+
+        return (fOriginX == iga.fOriginX &&
+                fOriginY == iga.fOriginY &&
+                getAlignment() == iga.getAlignment() &&
+                fImage.equals(iga.fImage));
+    }
+
+    /**
+     * Compares the specified Object with this ImageGraphicAttribute object.
+     *  
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified Object is equal to this
+     * ImageGraphicAttribute object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        try {
+            return equals((ImageGraphicAttribute) obj);
+        }
+        catch(ClassCastException e) {
+            return false;
+        }
+
+    }
+
+    @Override
+    public void draw(Graphics2D g2, float x, float y) {
+        g2.drawImage(fImage, (int)(x - fOriginX), (int)(y - fOriginY), null);
+    }
+
+    /** 
+     * @see java.awt.font.GraphicAttribute#getAdvance()
+     */
+    @Override
+    public float getAdvance() {
+        return Math.max(0, fImgWidth - fOriginX);
+    }
+
+    @Override
+    public float getAscent() {
+        return Math.max(0, fOriginY);
+    }
+
+    @Override
+    public Rectangle2D getBounds() {
+        return new Rectangle2D.Float(-fOriginX, -fOriginY, fImgWidth, fImgHeight);
+    }
+
+    /** 
+     * @see java.awt.font.GraphicAttribute#getDescent()
+     */
+    @Override
+    public float getDescent() {
+        return Math.max(0, fImgHeight - fOriginY);
+    }
+
+}
+
diff --git a/awt/java/awt/font/LineBreakMeasurer.java b/awt/java/awt/font/LineBreakMeasurer.java
new file mode 100644
index 0000000..efce615
--- /dev/null
+++ b/awt/java/awt/font/LineBreakMeasurer.java
@@ -0,0 +1,231 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.text.AttributedCharacterIterator;
+//???AWT: import java.text.BreakIterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The class LineBreakMeasurer provides methods to measure the graphical 
+ * representation of a text in order to determine where to add line 
+ * breaks so the resulting line of text fits its wrapping width. 
+ * The wrapping width defines the visual width of the paragraph.
+ */
+public final class LineBreakMeasurer {
+    
+    /** The tm. */
+    private TextMeasurer tm = null;
+    //???AWT private BreakIterator bi = null;
+    /** The position. */
+    private int position = 0;
+    
+    /** The maxpos. */
+    int maxpos = 0;
+
+    /**
+     * Instantiates a new LineBreakMeasurer object for the specified text.
+     * 
+     * @param text the AttributedCharacterIterator object which contains
+     * text with at least one character.
+     * @param frc the FontRenderContext represented information
+     * about graphic device.
+     */
+    public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
+        //???AWT: this(text, BreakIterator.getLineInstance(), frc);
+    }
+
+    /* ???AWT
+    public LineBreakMeasurer(
+            AttributedCharacterIterator text,
+            BreakIterator bi,
+            FontRenderContext frc
+    ) {
+        tm = new TextMeasurer(text, frc);
+        this.bi = bi;
+        this.bi.setText(text);
+        position = text.getBeginIndex();
+        maxpos = tm.aci.getEndIndex();
+    }
+    */
+
+    /**
+     * Deletes a character from the specified position of the text, 
+     * updates this LineBreakMeasurer object.
+     * 
+     * @param newText the new text.
+     * @param pos the posion of the character which is deleted.
+     */
+    public void deleteChar(AttributedCharacterIterator newText, int pos) {
+        tm.deleteChar(newText, pos);
+        //???AWT: bi.setText(newText);
+
+        position = newText.getBeginIndex();
+
+        maxpos--;
+    }
+
+    /**
+     * Gets current position of this LineBreakMeasurer.
+     * 
+     * @return current position of this LineBreakMeasurer
+     */
+    public int getPosition() {
+        return position;
+    }
+
+    /**
+     * Insertes a character at the specified position in the text, 
+     * updates this LineBreakMeasurer object.
+     * 
+     * @param newText the new text.
+     * @param pos the posion of the character which is inserted.
+     */
+    public void insertChar(AttributedCharacterIterator newText, int pos) {
+        tm.insertChar(newText, pos);
+//      ???AWT: bi.setText(newText);
+
+        position = newText.getBeginIndex();
+
+        maxpos++;
+    }
+
+    /**
+     * Returns the next line of text, updates current position in this 
+     * LineBreakMeasurer.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * @param offsetLimit the limit point withing the text indicating
+     * that no further text should be included on the line; the paragraph break.
+     * @param requireNextWord if true, null is returned (the entire word at the current 
+     * position does not fit within the wrapping width);  
+     * if false, a valid layout is returned that includes at least the 
+     * character at the current position.
+     * 
+     * @return the next TextLayout which begins at the current position and 
+     * represents the next line of text with width wrappingWidth, null is 
+     * returned if the entire word at the current position does not fit within 
+     * the wrapping width.
+     */
+    public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
+        if (position == maxpos) {
+            return null;
+        }
+
+        int nextPosition = nextOffset(wrappingWidth, offsetLimit, requireNextWord);
+
+        if (nextPosition == position) {
+            return null;
+        }
+        TextLayout layout = tm.getLayout(position, nextPosition);
+        position = nextPosition;
+        return layout;
+    }
+
+    /**
+     * Returns the next line of text.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * 
+     * @return the next line of text.
+     */
+    public TextLayout nextLayout(float wrappingWidth) {
+        return nextLayout(wrappingWidth, maxpos, false);
+    }
+
+    /**
+     * Returns the end position of the next line of text.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * 
+     * @return the end position of the next line of text.
+     */
+    public int nextOffset(float wrappingWidth) {
+        return nextOffset(wrappingWidth, maxpos, false);
+    }
+
+    /**
+     * Returns the end position of the next line of text.
+     * 
+     * @param wrappingWidth the maximum visible line width.
+     * @param offsetLimit the limit point withing the text indicating
+     * that no further text should be included on the line; the paragraph break.
+     * @param requireNextWord if true, the current position is returned 
+     * if the entire next word does not fit within wrappingWidth; 
+     * if false, the offset returned is at least one greater than the current
+     * position.
+     * 
+     * @return the end position of the next line of text.
+     * 
+     * @throws IllegalArgumentException if the offsetLimit is less than 
+     * the current position.
+     */
+    public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord) {
+        if (offsetLimit <= position) {
+            // awt.203=Offset limit should be greater than current position. 
+            throw new IllegalArgumentException(Messages.getString("awt.203")); //$NON-NLS-1$
+        }
+
+        if (position == maxpos) {
+            return position;
+        }
+
+        int breakPos = tm.getLineBreakIndex(position, wrappingWidth);
+        int correctedPos = breakPos;
+
+        // This check is required because bi.preceding(maxpos) throws an exception
+        /* ???AWT
+        if (breakPos == maxpos) {
+            correctedPos = maxpos;
+        } else if (Character.isWhitespace(bi.getText().setIndex(breakPos))) {
+            correctedPos = bi.following(breakPos);
+        } else {
+            correctedPos = bi.preceding(breakPos);
+        }
+        */
+        
+        if (position >= correctedPos) {
+            if (requireNextWord) {
+                correctedPos = position;
+            } else {
+                correctedPos = Math.max(position+1, breakPos);
+            }
+        }
+
+        return Math.min(correctedPos, offsetLimit);
+    }
+
+    /**
+     * Sets the new position of this LineBreakMeasurer.
+     * 
+     * @param pos the new position of this LineBreakMeasurer.
+     */
+    public void setPosition(int pos) {
+        if (tm.aci.getBeginIndex() > pos || maxpos < pos) {
+            // awt.33=index is out of range
+            throw new IllegalArgumentException(Messages.getString("awt.33")); //$NON-NLS-1$
+        }
+        position = pos;
+    }
+}
+
diff --git a/awt/java/awt/font/LineMetrics.java b/awt/java/awt/font/LineMetrics.java
new file mode 100644
index 0000000..2857187
--- /dev/null
+++ b/awt/java/awt/font/LineMetrics.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.
+ */
+/**
+ * @author Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+/**
+ * The LineMetrics class provides information such as concerning how the text 
+ * is positioned with respect to the base line, such as ascent, descent, 
+ * and leading.
+ * 
+ */
+public abstract class LineMetrics {
+
+    /**
+     * Gets the baseline offsets of the text according to the 
+     * the baseline of this text.
+     * 
+     * @return the baseline offsets of the text according to the 
+     * the baseline of this text.
+     */
+    public abstract float[] getBaselineOffsets();
+
+    /**
+     * Gets the number of characters of the text.
+     * 
+     * @return the number of characters of the text.
+     */
+    public abstract int getNumChars();
+
+    /**
+     * Gets the baseline index, returns one of the following 
+     * index: ROMAN_BASELINE, CENTER_BASELINE, HANGING_BASELINE.
+     * 
+     * @return the baseline index: ROMAN_BASELINE, CENTER_BASELINE
+     * or HANGING_BASELINE.
+     */
+    public abstract int getBaselineIndex();
+
+    /**
+     * Gets the thickness of the underline.
+     * 
+     * @return the thickness of the underline.
+     */
+    public abstract float getUnderlineThickness();
+
+    /**
+     * Gets the offset of the underline.
+     * 
+     * @return the offset of the underline.
+     */
+    public abstract float getUnderlineOffset();
+
+    /**
+     * Gets the thickness of strike through line.
+     * 
+     * @return the thickness of strike through line.
+     */
+    public abstract float getStrikethroughThickness();
+
+    /**
+     * Gets the offset of the strike through line.
+     * 
+     * @return the offset of the strike through line.
+     */
+    public abstract float getStrikethroughOffset();
+
+    /**
+     * Gets the leading of the text.
+     * 
+     * @return the leading of the text.
+     */
+    public abstract float getLeading();
+
+    /**
+     * Gets the height of the text as a sum of the ascent, the descent 
+     * and the leading.
+     * 
+     * @return the height of the text as a sum of the ascent, the descent 
+     * and the leading.
+     */
+    public abstract float getHeight();
+
+    /**
+     * Gets the descent of the text.
+     * 
+     * @return the descent of the text.
+     */
+    public abstract float getDescent();
+
+    /**
+     * Gets the ascent of the text.
+     * 
+     * @return the ascent of the text.
+     */
+    public abstract float getAscent();
+
+}
+
diff --git a/awt/java/awt/font/MultipleMaster.java b/awt/java/awt/font/MultipleMaster.java
new file mode 100644
index 0000000..773bfcf
--- /dev/null
+++ b/awt/java/awt/font/MultipleMaster.java
@@ -0,0 +1,86 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.Font;
+
+/**
+ * The MultipleMaster interface provides methods to manipulate MultipleMaster 
+ * type fonts and retrieve graphical and design data from them.
+ */
+public interface MultipleMaster {
+
+    /**
+     * Derives a new multiple master font based on the specified 
+     * parameters.
+     * 
+     * @param glyphWidths float array which represents width of each glyph
+     * in font space.
+     * @param avgStemWidth the average stem width in font space.
+     * @param typicalCapHeight the typical upper case char height.
+     * @param typicalXHeight the typical lower case char height.
+     * @param italicAngle the slope angle for italics.
+     * 
+     * @return a MultipleMaster font.
+     */
+    public Font deriveMMFont(float[] glyphWidths, float avgStemWidth,
+            float typicalCapHeight, float typicalXHeight, float italicAngle);
+
+    /**
+     * Derives a new multiple master font based on the design axis values 
+     * contained in the specified array. 
+     * 
+     * @param axes an float array which contains axis values.
+     * 
+     * @return a MultipleMaster font.
+     */
+    public Font deriveMMFont(float[] axes);
+
+    /**
+     * Gets default design values for the axes.
+     * 
+     * @return the default design values for the axes.
+     */
+    public float[] getDesignAxisDefaults();
+
+    /**
+     * Gets the array of design axis names. 
+     * 
+     * @return the array of design axis names. 
+     */
+    public String[] getDesignAxisNames();
+
+    /**
+     * Gets the array of design axis ranges. 
+     * 
+     * @return the array of design axis ranges.
+     */
+    public float[] getDesignAxisRanges();
+
+    /**
+     * Gets the number of multiple master design controls. 
+     * 
+     * @return the number of multiple master design controls.
+     */
+    public int getNumDesignAxes();
+
+}
+
diff --git a/awt/java/awt/font/OpenType.java b/awt/java/awt/font/OpenType.java
new file mode 100644
index 0000000..53cb6c0
--- /dev/null
+++ b/awt/java/awt/font/OpenType.java
@@ -0,0 +1,410 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+/**
+ * The OpenType interface provides constants and methods for getting 
+ * instance data for fonts of type OpenType and TrueType. For more information,
+ * see the <a href="http://partners.adobe.com/public/developer/opentype/index_spec.html">OpenType specification</a>.
+ */
+public interface OpenType {
+
+    /** 
+     * The Constant TAG_ACNT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_ACNT = 1633906292;
+
+    /** 
+     * The Constant TAG_AVAR indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_AVAR = 1635148146;
+
+    /** 
+     * The Constant TAG_BASE indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BASE = 1111577413;
+
+    /** 
+     * The Constant TAG_BDAT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BDAT = 1650745716;
+
+    /** 
+     * The Constant TAG_BLOC indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BLOC = 1651273571;
+
+    /** 
+     * The Constant TAG_BSLN indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_BSLN = 1651731566;
+
+    /** 
+     * The Constant TAG_CFF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CFF = 1128678944;
+
+    /** 
+     * The Constant TAG_CMAP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CMAP = 1668112752;
+
+    /** 
+     * The Constant TAG_CVAR indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CVAR = 1668702578;
+
+    /** 
+     * The Constant TAG_CVT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_CVT = 1668707360;
+
+    /** 
+     * The Constant TAG_DSIG indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_DSIG = 1146308935;
+
+    /** 
+     * The Constant TAG_EBDT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_EBDT = 1161970772;
+
+    /** 
+     * The Constant TAG_EBLC indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_EBLC = 1161972803;
+
+    /** 
+     * The Constant TAG_EBSC  indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_EBSC = 1161974595;
+
+    /** 
+     * The Constant TAG_FDSC indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_FDSC = 1717859171;
+
+    /** 
+     * The Constant TAG_FEAT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FEAT = 1717920116;
+
+    /** 
+     * The Constant TAG_FMTX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FMTX = 1718449272;
+
+    /** 
+     * The Constant TAG_FPGM indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FPGM = 1718642541;
+
+    /** 
+     * The Constant TAG_FVAR indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_FVAR = 1719034226;
+
+    /** 
+     * The Constant TAG_GASP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GASP = 1734439792;
+
+    /** 
+     * The Constant TAG_GDEF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GDEF = 1195656518;
+
+    /** 
+     * The Constant TAG_GLYF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GLYF = 1735162214;
+
+    /** 
+     * The Constant TAG_GPOS indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GPOS = 1196445523;
+
+    /** 
+     * The Constant TAG_GSUB indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_GSUB = 1196643650;
+
+    /** 
+     * The Constant TAG_GVAR indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_GVAR = 1735811442;
+
+    /** 
+     * The Constant TAG_HDMX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HDMX = 1751412088;
+
+    /** 
+     * The Constant TAG_HEAD indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HEAD = 1751474532;
+
+    /** 
+     * The Constant TAG_HHEA indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HHEA = 1751672161;
+
+    /** 
+     * The Constant TAG_HMTX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_HMTX = 1752003704;
+
+    /** 
+     * The Constant TAG_JSTF indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_JSTF = 1246975046;
+
+    /** 
+     * The Constant TAG_JUST indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_JUST = 1786082164;
+
+    /** 
+     * The Constant TAG_KERN indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_KERN = 1801810542;
+
+    /** 
+     * The Constant TAG_LCAR indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_LCAR = 1818452338;
+
+    /** 
+     * The Constant TAG_LOCA indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_LOCA = 1819239265;
+
+    /** 
+     * The Constant TAG_LTSH indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_LTSH = 1280594760;
+
+    /** 
+     * The Constant TAG_MAXP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MAXP = 1835104368;
+
+    /** 
+     * The Constant TAG_MMFX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MMFX = 1296909912;
+
+    /** 
+     * The Constant TAG_MMSD indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MMSD = 1296913220;
+
+    /** 
+     * The Constant TAG_MORT indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_MORT = 1836020340;
+
+    /** 
+     * The Constant TAG_NAME indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_NAME = 1851878757;
+
+    /** 
+     * The Constant TAG_OPBD indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_OPBD = 1836020340;
+
+    /** 
+     * The Constant TAG_OS2 indicates corresponding table tag 
+     * in the Open Type Specification. 
+     */
+    public static final int TAG_OS2 = 1330851634;
+
+    /** 
+     * The Constant TAG_PCLT  indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_PCLT = 1346587732;
+
+    /** 
+     * The Constant TAG_POST indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_POST = 1886352244;
+
+    /** 
+     * The Constant TAG_PREP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_PREP = 1886545264;
+
+    /** 
+     * The Constant TAG_PROP indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_PROP = 1886547824;
+
+    /** 
+     * The Constant TAG_TRAK indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_TRAK = 1953653099;
+
+    /** 
+     * The Constant TAG_TYP1 indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_TYP1 = 1954115633;
+
+    /** 
+     * The Constant TAG_VDMX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_VDMX = 1447316824;
+
+    /** 
+     * The Constant TAG_VHEA indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_VHEA = 1986553185;
+
+    /** 
+     * The Constant TAG_VMTX indicates corresponding table tag 
+     * in the Open Type Specification.
+     */
+    public static final int TAG_VMTX = 1986884728;
+
+    /**
+     * Returns the OpenType font version.
+     * 
+     * @return the the OpenType font version.
+     */
+    public int getVersion();
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items. 
+     *  
+     * @param sfntTag the sfnt tag.
+     * 
+     * @return a byte array contains the font data corresponding 
+     * to the specified tag.
+     */
+    public byte[] getFontTable(int sfntTag);
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items. 
+     *  
+     * @param sfntTag the sfnt tag.
+     * @param offset the offset of the returned table.
+     * @param count the number of returned table.
+     * 
+     * @return the table corresponding to sfntTag and containing 
+     * the bytes starting at offset byte and including count bytes.
+     */
+    public byte[] getFontTable(int sfntTag, int offset, int count);
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items.
+     * 
+     * @param strSfntTag the str sfnt tag as a String.
+     * 
+     * @return a byte array contains the font data corresponding 
+     * to the specified tag.
+     */
+    public byte[] getFontTable(String strSfntTag);
+
+    /**
+     * Gets the table for a specified tag. 
+     * Sfnt tables include cmap, name and head items. 
+     *  
+     * @param strSfntTag the sfnt tag as a String.
+     * @param offset the offset of the returned table.
+     * @param count the number of returned table.
+     * 
+     * @return the table corresponding to sfntTag and containing 
+     * the bytes starting at offset byte and including count bytes.
+     */
+    public byte[] getFontTable(String strSfntTag, int offset, int count);
+
+    /**
+     * Gets the table size for a specified tag. 
+     * 
+     * @param strSfntTag the sfnt tag as a String.
+     * 
+     * @return the table size for a specified tag.
+     */
+    public int getFontTableSize(String strSfntTag);
+
+    /**
+     * Gets the table size for a specified tag. 
+     * 
+     * @param sfntTag the sfnt tag.
+     * 
+     * @return the table size for a specified tag.
+     */
+    public int getFontTableSize(int sfntTag);
+
+}
+
diff --git a/awt/java/awt/font/ShapeGraphicAttribute.java b/awt/java/awt/font/ShapeGraphicAttribute.java
new file mode 100644
index 0000000..45199fd
--- /dev/null
+++ b/awt/java/awt/font/ShapeGraphicAttribute.java
@@ -0,0 +1,195 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.BasicStroke;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The ShapeGraphicAttribute class provides an opportunity to insert 
+ * shapes to a text.
+ */
+public final class ShapeGraphicAttribute extends GraphicAttribute {
+
+    // shape to render
+    /** The shape. */
+    private Shape fShape;
+    
+    // flag, if the shape should be stroked (true) or filled (false)
+    /** The stroke. */
+    private boolean fStroke;
+
+    // bounds of the shape
+    /** The bounds. */
+    private Rectangle2D fBounds;
+    
+    // X coordinate of the origin point
+    /** The origin x. */
+    private float fOriginX;
+    
+    // Y coordinate of the origin point
+    /** The origin y. */
+    private float fOriginY;
+
+    // width of the shape
+    /** The shape width. */
+    private float fShapeWidth;
+    
+    // height of the shape
+    /** The shape height. */
+    private float fShapeHeight;
+
+    /** 
+     * The Constant STROKE indicates whether the Shape is stroked 
+     * or not. 
+     */
+    public static final boolean STROKE = true;
+
+    /** 
+     * The Constant FILL indicates whether the Shape is filled 
+     * or not. */
+    public static final boolean FILL = false;
+
+    /**
+     * Instantiates a new ShapeGraphicAttribute object for the specified 
+     * Shape.
+     * 
+     * @param shape the shape to be rendered by this 
+     * ShapeGraphicAttribute.
+     * @param alignment the alignment of this ShapeGraphicAttribute.
+     * @param stroke true if the Shape is stroked,
+     *  false if the Shape is filled.
+     */
+    public ShapeGraphicAttribute(Shape shape, int alignment, boolean stroke) {
+        super(alignment);
+
+        this.fShape = shape;
+        this.fStroke = stroke;
+
+        this.fBounds  = fShape.getBounds2D();
+
+        this.fOriginX = (float)fBounds.getMinX();
+        this.fOriginY = (float)fBounds.getMinY();
+
+        this.fShapeWidth = (float)fBounds.getWidth();
+        this.fShapeHeight = (float)fBounds.getHeight();
+    }
+
+    /**
+     * Returns a hash code of this ShapeGraphicAttribute object.
+     * 
+     * @return a hash code of this ShapeGraphicAttribute object.
+     */
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+
+        hash.append(fShape.hashCode());
+        hash.append(getAlignment());
+        return hash.hashCode();
+    }
+
+    /**
+     * Compares this ShapeGraphicAttribute object to the specified
+     * ShapeGraphicAttribute object.
+     * 
+     * @param sga the ShapeGraphicAttribute object to be compared.
+     * 
+     * @return true, if this ShapeGraphicAttribute object is equal
+     * to the specified ShapeGraphicAttribute object, false otherwise.
+     */
+    public boolean equals(ShapeGraphicAttribute sga) {
+        if (sga == null) {
+            return false;
+        }
+
+        if (sga == this) {
+            return true;
+        }
+
+        return ( fStroke == sga.fStroke &&
+                getAlignment() == sga.getAlignment() &&
+                fShape.equals(sga.fShape));
+
+    }
+
+    /**
+     * Compares this ShapeGraphicAttribute object to the specified
+     * Object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if this ShapeGraphicAttribute object is equal
+     * to the specified Object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        try {
+            return equals((ShapeGraphicAttribute) obj);
+        }
+        catch(ClassCastException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public void draw(Graphics2D g2, float x, float y) {
+        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
+        if (fStroke == STROKE){
+            Stroke oldStroke = g2.getStroke();
+            g2.setStroke(new BasicStroke());
+            g2.draw(at.createTransformedShape(fShape));
+            g2.setStroke(oldStroke);
+        } else {
+            g2.fill(at.createTransformedShape(fShape));
+        }
+
+    }
+
+    @Override
+    public float getAdvance() {
+        return Math.max(0, fShapeWidth + fOriginX);
+    }
+
+    @Override
+    public float getAscent() {
+        return Math.max(0, -fOriginY);
+    }
+
+    @Override
+    public Rectangle2D getBounds() {
+        return (Rectangle2D)fBounds.clone();
+    }
+
+    @Override
+    public float getDescent() {
+        return Math.max(0, fShapeHeight + fOriginY);
+    }
+
+}
+
diff --git a/awt/java/awt/font/TextHitInfo.java b/awt/java/awt/font/TextHitInfo.java
new file mode 100644
index 0000000..17bbf71
--- /dev/null
+++ b/awt/java/awt/font/TextHitInfo.java
@@ -0,0 +1,216 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import org.apache.harmony.misc.HashCode;
+
+
+/**
+ * The TextHitInfo class provides information about a caret position 
+ * in a text model for insertion or deletion of a character in a text.
+ * The TextHitInfo defines two biases of the character: leading or trailing.
+ * Leading position means the left edge of the specified character 
+ * (TextHitInfo.leading(2) method for "text" returns the left side of "x").
+ * Trailing position means the right edge of the specified character
+ * (TextHitInfo.trailing(2) method for "text" returns the right side of "x").
+ */
+public final class TextHitInfo {
+    
+    /** The char idx. */
+    private int charIdx; // Represents character index in the line
+    
+    /** The is trailing. */
+    private boolean isTrailing;
+
+    /**
+     * Instantiates a new text hit info.
+     * 
+     * @param idx the idx
+     * @param isTrailing the is trailing
+     */
+    private TextHitInfo(int idx, boolean isTrailing) {
+        charIdx = idx;
+        this.isTrailing = isTrailing;
+    }
+
+    /**
+     * To string.
+     * 
+     * @return the string
+     */
+    @Override
+    public String toString() {
+        return new String(
+                "TextHitInfo[" + charIdx + ", " + //$NON-NLS-1$ //$NON-NLS-2$
+                (isTrailing?"Trailing":"Leading") + "]" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        );
+    }
+
+    /**
+     * Compares this TextHitInfo object with the specified object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if the specified object is a TextHitInfo object 
+     * with the same data values as this TextHitInfo, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof TextHitInfo) {
+            return equals((TextHitInfo) obj);
+        }
+        return false;
+    }
+
+    /**
+     * Compares this TextHitInfo object with the specified TextHitInfo
+     * object.
+     * 
+     * @param thi the TextHitInfo object to be compared.
+     * 
+     * @return true, if this TextHitInfo object has the same data values as the
+     * specified TextHitInfo object, false otherwise.
+     */
+    public boolean equals(TextHitInfo thi) {
+        return
+                thi != null &&
+                thi.charIdx == charIdx &&
+                thi.isTrailing == isTrailing;
+    }
+
+    /**
+     * Gets a TextHitInfo object with its character index 
+     * at the specified offset from the character index of 
+     * this TextHitInfo.
+     * 
+     * @param offset the offset.
+     * 
+     * @return the TextHitInfo. 
+     */
+    public TextHitInfo getOffsetHit(int offset) {
+        return new TextHitInfo(charIdx + offset, isTrailing);
+    }
+
+    /**
+     * Gets a TextHitInfo associated with the other side of 
+     * the insertion point. 
+     *  
+     * @return the other hit.
+     */
+    public TextHitInfo getOtherHit() {
+        return isTrailing ?
+                new TextHitInfo(charIdx+1, false) :
+                new TextHitInfo(charIdx-1, true);
+    }
+
+    /**
+     * Returns true if the leading edge of the character is hit,
+     * false if the trailing edge of the character is hit.
+     * 
+     * @return true if the leading edge of the character is hit,
+     * false if the trailing edge of the character is hit.
+     */
+    public boolean isLeadingEdge() {
+        return !isTrailing;
+    }
+
+    /**
+     * Hash code.
+     * 
+     * @return the int
+     */
+    @Override
+    public int hashCode() {
+        return HashCode.combine(charIdx, isTrailing);
+    }
+
+    /**
+     * Gets the insertion index.
+     * 
+     * @return the insertion index: character index if the leading edge
+     * is hit, or character index + 1 if the trailing edge is hit.   
+     */
+    public int getInsertionIndex() {
+        return isTrailing ? charIdx+1 : charIdx;
+    }
+
+    /**
+     * Gets the index of the character hit.
+     * 
+     * @return the character hit's index.
+     */
+    public int getCharIndex() {
+        return charIdx;
+    }
+
+    /**
+     * Returns a TextHitInfo associated with the trailing edge of 
+     * the character at the specified char index.
+     * 
+     * @param charIndex the char index.
+     * 
+     * @return the TextHitInfo associated with the trailing edge of 
+     * the character at the specified char index.
+     */
+    public static TextHitInfo trailing(int charIndex) {
+        return new TextHitInfo(charIndex, true);
+    }
+
+    /**
+     * Returns a TextHitInfo object associated with the leading edge 
+     * of the character at the specified char index.
+     * 
+     * @param charIndex the char index.
+     * 
+     * @return the TextHitInfo object associated with the leading edge 
+     * of the character at the specified char index.
+     */
+    public static TextHitInfo leading(int charIndex) {
+        return new TextHitInfo(charIndex, false);
+    }
+
+    /**
+     * Returns a (trailing) TextHitInfo object associated with the character 
+     * before the specified offset.
+     * 
+     * @param offset the offset.
+     * 
+     * @return the TextHitInfo object associated with the character 
+     * before the specified offset.
+     */
+    public static TextHitInfo beforeOffset(int offset) {
+        return new TextHitInfo(offset-1, true);
+    }
+
+    /**
+     * Returns a (leading) TextHitInfo object associated with the character 
+     * after the specified offset.
+     * 
+     * @param offset the offset.
+     * 
+     * @return the TextHitInfo object associated with the character 
+     * after the specified offset.
+     */
+    public static TextHitInfo afterOffset(int offset) {
+        return new TextHitInfo(offset, false);
+    }
+}
diff --git a/awt/java/awt/font/TextLayout.java b/awt/java/awt/font/TextLayout.java
new file mode 100644
index 0000000..e80afd0
--- /dev/null
+++ b/awt/java/awt/font/TextLayout.java
@@ -0,0 +1,916 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.GeneralPath;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.util.Map;
+
+import org.apache.harmony.awt.gl.font.BasicMetrics;
+import org.apache.harmony.awt.gl.font.CaretManager;
+import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
+import org.apache.harmony.awt.gl.font.TextRunBreaker;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The TextLayout class defines the graphical representation of character data.
+ * This class provides method for obtaining information about cursor 
+ * positioning and movement, split cursors for text with different directions, 
+ * logical and visual highlighting, multiple baselines, hits, justification, 
+ * ascent, descent, and advance, and rendering. A TextLayout object can be 
+ * rendered using Graphics context. 
+ */
+public final class TextLayout implements Cloneable {
+
+    /**
+     * The CaretPolicy class provides a policy for obtaining the 
+     * caret location. The single getStrongCaret method specifies 
+     * the policy.
+     */
+    public static class CaretPolicy {
+
+        /**
+         * Instantiates a new CaretPolicy.
+         */
+        public CaretPolicy() {
+            // Nothing to do
+        }
+
+        /**
+         * Returns whichever of the two specified TextHitInfo objects 
+         * has the stronger caret (higher character level) in the 
+         * specified TextLayout.
+         * 
+         * @param hit1 the first TextHitInfo of the specified TextLayout.
+         * @param hit2 the second TextHitInfo of the specified TextLayout.
+         * @param layout the TextLayout.
+         * 
+         * @return the TextHitInfo with the stronger caret.
+         */
+        public TextHitInfo getStrongCaret(TextHitInfo hit1, TextHitInfo hit2, TextLayout layout) {
+            // Stronger hit is the one with greater level.
+            // If the level is same, leading edge is stronger.
+
+            int level1 = layout.getCharacterLevel(hit1.getCharIndex());
+            int level2 = layout.getCharacterLevel(hit2.getCharIndex());
+
+            if (level1 == level2) {
+                return (hit2.isLeadingEdge() && (!hit1.isLeadingEdge())) ? hit2 : hit1;
+            }
+            return level1 > level2 ? hit1 : hit2;
+        }
+
+    }
+
+    /** 
+     * The Constant DEFAULT_CARET_POLICY indicates the default caret policy.
+     */
+    public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy();
+
+    /** The breaker. */
+    private TextRunBreaker breaker;
+    
+    /** The metrics valid. */
+    private boolean metricsValid = false;
+    
+    /** The tmc. */
+    private TextMetricsCalculator tmc;
+    
+    /** The metrics. */
+    private BasicMetrics metrics;
+    
+    /** The caret manager. */
+    private CaretManager caretManager;
+    
+    /** The justification width. */
+    float justificationWidth = -1;
+
+    /**
+     * Instantiates a new TextLayout object from the specified string
+     * and Font.
+     * 
+     * @param string the string to be displayed.
+     * @param font the font of the text.
+     * @param frc the FontRenderContext object for obtaining
+     * information about a graphics device.
+     */
+    public TextLayout(String string, Font font, FontRenderContext frc) {
+        if (string == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (font == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "font")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (string.length() == 0){
+            // awt.02='{0}' parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        AttributedString as = new AttributedString(string);
+        as.addAttribute(TextAttribute.FONT, font);
+        this.breaker = new TextRunBreaker(as.getIterator(), frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new TextLayout from the specified text and 
+     * a map of attributes.
+     * 
+     * @param string the string to be displayed.
+     * @param attributes the attributes to be used for obtaining the text 
+     * style.
+     * @param frc the FontRenderContext object for obtaining
+     * information about a graphics device.
+     */
+    public TextLayout(
+            String string,
+            Map<? extends java.text.AttributedCharacterIterator.Attribute, ?> attributes,
+            FontRenderContext frc ) {
+        if (string == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (attributes == null){
+            // awt.01='{0}' parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.01", "attributes")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (string.length() == 0){
+            // awt.02='{0}' parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.02", "string")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        
+        AttributedString as = new AttributedString(string);
+        as.addAttributes(attributes, 0, string.length());
+        this.breaker = new TextRunBreaker(as.getIterator(), frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new TextLayout from the AttributedCharacterIterator.
+     * 
+     * @param text the AttributedCharacterIterator.
+     * @param frc the FontRenderContext object for obtaining
+     * information about a graphics device.
+     */
+    public TextLayout(AttributedCharacterIterator text, FontRenderContext frc) {
+        if (text == null){
+            // awt.03='{0}' iterator parameter is null
+            throw new IllegalArgumentException(Messages.getString("awt.03", "text")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        
+        if (text.getBeginIndex() == text.getEndIndex()){
+            // awt.04='{0}' iterator parameter has zero length
+            throw new IllegalArgumentException(Messages.getString("awt.04", "text")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        this.breaker = new TextRunBreaker(text, frc);
+        caretManager = new CaretManager(breaker);
+    }
+
+    /**
+     * Instantiates a new text layout.
+     * 
+     * @param breaker the breaker
+     */
+    TextLayout(TextRunBreaker breaker) {
+        this.breaker = breaker;
+        caretManager = new CaretManager(this.breaker);
+    }
+
+    /**
+     * Returns a hash code of this TextLayout object.
+     * 
+     * @return a hash code of this TextLayout object.
+     */
+    @Override
+    public int hashCode() {
+        return breaker.hashCode();
+    }
+
+    /**
+     * Returns a copy of this object.
+     * 
+     * @return a copy of this object.
+     */
+    @Override
+    protected Object clone() {
+        TextLayout res = new TextLayout((TextRunBreaker) breaker.clone());
+
+        if (justificationWidth >= 0) {
+            res.handleJustify(justificationWidth);
+        }
+
+        return res;
+    }
+
+    /**
+     * Compares this TextLayout object to the specified TextLayout object.
+     * 
+     * @param layout the TextLayout object to be compared.
+     * 
+     * @return true, if this TextLayout object is equal to 
+     * the specified TextLayout object, false otherwise.
+     */
+    public boolean equals(TextLayout layout) {
+        if (layout == null) {
+            return false;
+        }
+        return this.breaker.equals(layout.breaker);
+    }
+
+    /**
+     * Compares this TextLayout object to the specified Object.
+     * 
+     * @param obj the Object to be compared.
+     * 
+     * @return true, if this TextLayout object is equal to 
+     * the specified Object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof TextLayout ? equals((TextLayout) obj) : false;
+    }
+
+    /**
+     * Gets the string representation for this TextLayout.
+     * 
+     * @return the string representation for this TextLayout.
+     */
+    @Override
+    public String toString() { // what for?
+        return super.toString();
+    }
+
+    /**
+     * Draws this TextLayout at the specified location with the 
+     * specified Graphics2D context. 
+     * 
+     * @param g2d the Graphics2D object which renders this TextLayout.
+     * @param x the X coordinate of the TextLayout origin. 
+     * @param y the Y coordinate of the TextLayout origin.
+     */
+    public void draw(Graphics2D g2d, float x, float y) {
+        updateMetrics();
+        breaker.drawSegments(g2d, x ,y);
+    }
+
+    /**
+     * Update metrics.
+     */
+    private void updateMetrics() {
+        if (!metricsValid) {
+            breaker.createAllSegments();
+            tmc = new TextMetricsCalculator(breaker);
+            metrics = tmc.createMetrics();
+            metricsValid = true;
+        }
+    }
+
+    /**
+     * Gets the advance of this TextLayout object.
+     * 
+     * @return the advance of this TextLayout object.
+     */
+    public float getAdvance() {
+        updateMetrics();
+        return metrics.getAdvance();
+    }
+
+    /**
+     * Gets the ascent of this TextLayout object.
+     * 
+     * @return the ascent of this TextLayout object.
+     */
+    public float getAscent() {
+        updateMetrics();
+        return metrics.getAscent();
+    }
+
+    /**
+     * Gets the baseline of this TextLayout object.
+     * 
+     * @return the baseline of this TextLayout object.
+     */
+    public byte getBaseline() {
+        updateMetrics();
+        return (byte) metrics.getBaseLineIndex();
+    }
+
+    /**
+     * Gets the float array of offsets for the baselines which 
+     * are used in this TextLayout.
+     * 
+     * @return the float array of offsets for the baselines which 
+     * are used in this TextLayout.
+     */
+    public float[] getBaselineOffsets() {
+        updateMetrics();
+        return tmc.getBaselineOffsets();
+    }
+
+    /**
+     * Gets the black box bounds of the characters in the specified area. 
+     * The black box bounds is an Shape which contains all 
+     * bounding boxes of all the glyphs of the characters 
+     * between firstEndpoint and secondEndpoint parameters values.     
+     *  
+     * @param firstEndpoint the first point of the area.
+     * @param secondEndpoint the second point of the area.
+     * 
+     * @return the Shape which contains black box bounds.
+     */
+    public Shape getBlackBoxBounds(int firstEndpoint, int secondEndpoint) {
+        updateMetrics();
+        if (firstEndpoint < secondEndpoint) {
+            return breaker.getBlackBoxBounds(firstEndpoint, secondEndpoint);
+        }
+        return breaker.getBlackBoxBounds(secondEndpoint, firstEndpoint);
+    }
+
+    /**
+     * Gets the bounds of this TextLayout.
+     * 
+     * @return the bounds of this TextLayout.
+     */
+    public Rectangle2D getBounds() {
+        updateMetrics();
+        return breaker.getVisualBounds();
+    }
+
+    /**
+     * Gets information about the caret of the specified TextHitInfo.
+     * 
+     * @param hitInfo the TextHitInfo.
+     * 
+     * @return the information about the caret of the specified TextHitInfo.
+     */
+    public float[] getCaretInfo(TextHitInfo hitInfo) {
+        updateMetrics();
+        return caretManager.getCaretInfo(hitInfo);
+    }
+
+    /**
+     * Gets information about the caret of the specified TextHitInfo
+     * of a character in this TextLayout.
+     * 
+     * @param hitInfo the TextHitInfo of a character in this TextLayout.
+     * @param bounds the bounds to which the caret info is constructed.
+     * 
+     * @return the caret of the specified TextHitInfo.
+     */
+    public float[] getCaretInfo(TextHitInfo hitInfo, Rectangle2D bounds) {
+        updateMetrics();
+        return caretManager.getCaretInfo(hitInfo);
+    }
+
+    /**
+     * Gets a Shape which represents the caret of the specified TextHitInfo
+     * in the bounds of this TextLayout.
+     * 
+     * @param hitInfo the TextHitInfo.
+     * @param bounds the bounds to which the caret info is constructed.
+     * 
+     * @return the Shape which represents the caret.
+     */
+    public Shape getCaretShape(TextHitInfo hitInfo, Rectangle2D bounds) {
+        updateMetrics();
+        return caretManager.getCaretShape(hitInfo, this);
+    }
+
+    /**
+     * Gets a Shape which represents the caret of the specified TextHitInfo
+     * in the bounds of this TextLayout.
+     * 
+     * @param hitInfo the TextHitInfo.
+     * 
+     * @return the Shape which represents the caret.
+     */
+    public Shape getCaretShape(TextHitInfo hitInfo) {
+        updateMetrics();
+        return caretManager.getCaretShape(hitInfo, this);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets with
+     * default caret policy and null bounds: the first element 
+     * is the strong caret, the second is the weak caret or null. 
+     * 
+     * @param offset an offset in the TextLayout.
+     * 
+     * @return an array of two Shapes corresponded to the strong
+     * and weak carets.
+     */
+    public Shape[] getCaretShapes(int offset) {
+        return getCaretShapes(offset, null, TextLayout.DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets with
+     * the default caret policy: the first element is the strong 
+     * caret, the second is the weak caret or null.
+     * 
+     * @param offset an offset in the TextLayout.
+     * @param bounds the bounds to which to extend the carets.
+     * 
+     * @return an array of two Shapes corresponded to the strong
+     * and weak carets.
+     */
+    public Shape[] getCaretShapes(int offset, Rectangle2D bounds) {
+        return getCaretShapes(offset, bounds, TextLayout.DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets two Shapes for the strong and weak carets: the first
+     * element is the strong caret, the second is the weak caret 
+     * or null.
+     * 
+     * @param offset an offset in the TextLayout.
+     * @param bounds the bounds to which to extend the carets.
+     * @param policy the specified CaretPolicy.
+     * 
+     * @return an array of two Shapes corresponded to the strong
+     * and weak carets.
+     */
+    public Shape[] getCaretShapes(int offset, Rectangle2D bounds, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        updateMetrics();
+        return caretManager.getCaretShapes(offset, bounds, policy, this);
+    }
+
+    /**
+     * Gets the number of characters in this TextLayout.
+     * 
+     * @return the number of characters in this TextLayout.
+     */
+    public int getCharacterCount() {
+        return breaker.getCharCount();
+    }
+
+    /**
+     * Gets the level of the character with the specified index. 
+     *  
+     * @param index the specified index of the character.
+     * 
+     * @return the level of the character.
+     */
+    public byte getCharacterLevel(int index) {
+        if (index == -1 || index == getCharacterCount()) {
+            return (byte) breaker.getBaseLevel();
+        }
+        return breaker.getLevel(index);
+    }
+
+    /**
+     * Gets the descent of this TextLayout.
+     * 
+     * @return the descent of this TextLayout.
+     */
+    public float getDescent() {
+        updateMetrics();
+        return metrics.getDescent();
+    }
+
+    /**
+     * Gets the TextLayout wich is justified with the specified
+     * width related to this TextLayout.
+     * 
+     * @param justificationWidth the width which is used 
+     * for justification.
+     * 
+     * @return a TextLayout justified to the specified width.
+     * 
+     * @throws Error the error occures if this TextLayout has been
+     * already justified.
+     */
+    public TextLayout getJustifiedLayout(float justificationWidth) throws Error {
+        float justification = breaker.getJustification();
+
+        if (justification < 0) {
+            // awt.196=Justification impossible, layout already justified
+            throw new Error(Messages.getString("awt.196")); //$NON-NLS-1$
+        } else if (justification == 0) {
+            return this;
+        }
+
+        TextLayout justifiedLayout = new TextLayout((TextRunBreaker) breaker.clone());
+        justifiedLayout.handleJustify(justificationWidth);
+        return justifiedLayout;
+    }
+
+    /**
+     * Gets the leading of this TextLayout.
+     * 
+     * @return the leading of this TextLayout.
+     */
+    public float getLeading() {
+        updateMetrics();
+        return metrics.getLeading();
+    }
+
+    /**
+     * Gets a Shape representing the logical selection betweeen 
+     * the specified endpoints and extended to the natural 
+     * bounds of this TextLayout.
+     * 
+     * @param firstEndpoint the first selected endpoint within the area of characters
+     * @param secondEndpoint the second selected endpoint within the area of characters
+     * 
+     * @return a Shape represented the logical selection betweeen 
+     * the specified endpoints.
+     */
+    public Shape getLogicalHighlightShape(int firstEndpoint, int secondEndpoint) {
+        updateMetrics();
+        return getLogicalHighlightShape(firstEndpoint, secondEndpoint, breaker.getLogicalBounds());
+    }
+
+    /**
+     * Gets a Shape representing the logical selection betweeen 
+     * the specified endpoints and extended to the specified 
+     * bounds of this TextLayout.
+     * 
+     * @param firstEndpoint the first selected endpoint within the area of characters
+     * @param secondEndpoint the second selected endpoint within the area of characters
+     * @param bounds the specified bounds of this TextLayout.
+     * 
+     * @return a Shape represented the logical selection betweeen 
+     * the specified endpoints.
+     */
+    public Shape getLogicalHighlightShape(
+            int firstEndpoint,
+            int secondEndpoint,
+            Rectangle2D bounds
+    ) {
+        updateMetrics();
+
+        if (firstEndpoint > secondEndpoint) {
+            if (secondEndpoint < 0 || firstEndpoint > breaker.getCharCount()) {
+                // awt.197=Endpoints are out of range
+                throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
+            }
+            return caretManager.getLogicalHighlightShape(
+                    secondEndpoint,
+                    firstEndpoint,
+                    bounds,
+                    this
+            );
+        }
+        if (firstEndpoint < 0 || secondEndpoint > breaker.getCharCount()) {
+            // awt.197=Endpoints are out of range
+            throw new IllegalArgumentException(Messages.getString("awt.197")); //$NON-NLS-1$
+        }
+        return caretManager.getLogicalHighlightShape(
+                firstEndpoint,
+                secondEndpoint,
+                bounds,
+                this
+        );
+    }
+
+    /**
+     * Gets the logical ranges of text which corresponds to a visual 
+     * selection.
+     * 
+     * @param hit1 the first endpoint of the visual range.
+     * @param hit2 the second endpoint of the visual range.
+     * 
+     * @return the logical ranges of text which corresponds to a visual 
+     * selection.
+     */
+    public int[] getLogicalRangesForVisualSelection(TextHitInfo hit1, TextHitInfo hit2) {
+        return caretManager.getLogicalRangesForVisualSelection(hit1, hit2);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified offset. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * 
+     * @return the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified hit, or null 
+     * if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(int offset) {
+        return getNextLeftHit(offset, DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified hit. 
+     * 
+     * @param hitInfo the initial hit.
+     * 
+     * @return the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified hit, or null 
+     * if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(TextHitInfo hitInfo) {
+        breaker.createAllSegments();
+        return caretManager.getNextLeftHit(hitInfo);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the left (or
+     * up at the end of the line) of the specified offset, given the 
+     * specified caret policy. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * @param policy the policy to be used for obtaining the strong caret.
+     * 
+     * @return the TextHitInfo for the next caret to the left of the 
+     * specified offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextLeftHit(int offset, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        TextHitInfo hit = TextHitInfo.afterOffset(offset);
+        TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
+        TextHitInfo nextLeftHit = getNextLeftHit(strongHit);
+
+        if (nextLeftHit != null) {
+            return policy.getStrongCaret(getVisualOtherHit(nextLeftHit), nextLeftHit, this);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified hit. 
+     * 
+     * @param hitInfo the initial hit.
+     * 
+     * @return the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified hit, or null 
+     * if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(TextHitInfo hitInfo) {
+        breaker.createAllSegments();
+        return caretManager.getNextRightHit(hitInfo);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified offset. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * 
+     * @return the TextHitInfo for the next caret to the right of the 
+     * specified offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(int offset) {
+        return getNextRightHit(offset, DEFAULT_CARET_POLICY);
+    }
+
+    /**
+     * Gets the TextHitInfo for the next caret to the right (or
+     * down at the end of the line) of the specified offset, given the 
+     * specified caret policy. 
+     * 
+     * @param offset the offset in this TextLayout.
+     * @param policy the policy to be used for obtaining the strong caret.
+     * 
+     * @return the TextHitInfo for the next caret to the right of the 
+     * specified offset, or null if there is no hit.
+     */
+    public TextHitInfo getNextRightHit(int offset, TextLayout.CaretPolicy policy) {
+        if (offset < 0 || offset > breaker.getCharCount()) {
+            // awt.195=Offset is out of bounds
+            throw new IllegalArgumentException(Messages.getString("awt.195")); //$NON-NLS-1$
+        }
+
+        TextHitInfo hit = TextHitInfo.afterOffset(offset);
+        TextHitInfo strongHit = policy.getStrongCaret(hit, hit.getOtherHit(), this);
+        TextHitInfo nextRightHit = getNextRightHit(strongHit);
+
+        if (nextRightHit != null) {
+            return policy.getStrongCaret(getVisualOtherHit(nextRightHit), nextRightHit, this);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the outline of this TextLayout as a Shape.
+     * 
+     * @param xform the AffineTransform to be used to transform 
+     * the outline before returning it, or null if no transformation
+     * is desired.
+     * 
+     * @return the outline of this TextLayout as a Shape.
+     */
+    public Shape getOutline(AffineTransform xform) {
+        breaker.createAllSegments();
+
+        GeneralPath outline = breaker.getOutline();
+
+        if (outline != null && xform != null) {
+            outline.transform(xform);
+        }
+
+        return outline;
+    }
+
+    /**
+     * Gets the visible advance of this TextLayout which is defined as
+     * diffence between leading (advance) and trailing whitespace.
+     * 
+     * @return the visible advance of this TextLayout.
+     */
+    public float getVisibleAdvance() {
+        updateMetrics();
+
+        // Trailing whitespace _SHOULD_ be reordered (Unicode spec) to
+        // base direction, so it is also trailing
+        // in logical representation. We use this fact.
+        int lastNonWhitespace = breaker.getLastNonWhitespace();
+
+        if (lastNonWhitespace < 0) {
+            return 0;
+        } else if (lastNonWhitespace == getCharacterCount()-1) {
+            return getAdvance();
+        } else if (justificationWidth >= 0) { // Layout is justified
+            return justificationWidth;
+        } else {
+            breaker.pushSegments(
+                    breaker.getACI().getBeginIndex(),
+                    lastNonWhitespace + breaker.getACI().getBeginIndex() + 1
+            );
+
+            breaker.createAllSegments();
+
+            float visAdvance = tmc.createMetrics().getAdvance();
+
+            breaker.popSegments();
+            return visAdvance;
+        }
+    }
+
+    /**
+     * Gets a Shape which corresponds to the highlighted (selected) area
+     * based on two hit locations within the text and extends to the bounds.
+     * 
+     * @param hit1 the first text hit location.
+     * @param hit2 the second text hit location.
+     * @param bounds the rectangle that the highlighted area should be 
+     * extended or restricted to.
+     * 
+     * @return a Shape which corresponds to the highlighted (selected) area.
+     */
+    public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2, Rectangle2D bounds) {
+        return caretManager.getVisualHighlightShape(hit1, hit2, bounds, this);
+    }
+
+    /**
+     * Gets a Shape which corresponds to the highlighted (selected) area
+     * based on two hit locations within the text.
+     * 
+     * @param hit1 the first text hit location.
+     * @param hit2 the second text hit location.
+     * 
+     * @return a Shape which corresponds to the highlighted (selected) area.
+     */
+    public Shape getVisualHighlightShape(TextHitInfo hit1, TextHitInfo hit2) {
+        breaker.createAllSegments();
+        return caretManager.getVisualHighlightShape(hit1, hit2, breaker.getLogicalBounds(), this);
+    }
+
+    /**
+     * Gets the TextHitInfo for a hit on the opposite side of the 
+     * specified hit's caret.
+     * 
+     * @param hitInfo the specified TextHitInfo.
+     * 
+     * @return the TextHitInfo for a hit on the opposite side of the 
+     * specified hit's caret.
+     */
+    public TextHitInfo getVisualOtherHit(TextHitInfo hitInfo) {
+        return caretManager.getVisualOtherHit(hitInfo);
+    }
+
+    /**
+     * Justifies the text; this method should be overridden
+     * by subclasses.
+     * 
+     * @param justificationWidth the width for justification.
+     */
+    protected void handleJustify(float justificationWidth) {
+        float justification = breaker.getJustification();
+
+        if (justification < 0) {
+            // awt.196=Justification impossible, layout already justified
+            throw new IllegalStateException(Messages.getString("awt.196")); //$NON-NLS-1$
+        } else if (justification == 0) {
+            return;
+        }
+
+        float gap = (justificationWidth - getVisibleAdvance()) * justification;
+        breaker.justify(gap);
+        this.justificationWidth = justificationWidth;
+
+        // Correct metrics
+        tmc = new TextMetricsCalculator(breaker);
+        tmc.correctAdvance(metrics);
+    }
+
+    /**
+     * Returns a TextHitInfo object that gives information on which 
+     * division point (between two characters) is corresponds to a 
+     * hit (such as a mouse click) at the specified coordinates.
+     * 
+     * @param x the X coordinate in this TextLayout.
+     * @param y the Y coordinate in this TextLayout.
+     * 
+     * TextHitInfo object cooresponding to the given coordinates
+     * within the text.
+     */
+    public TextHitInfo hitTestChar(float x, float y) {
+        return hitTestChar(x, y, getBounds());
+    }
+
+    /**
+     * Returns a TextHitInfo object that gives information on which 
+     * division point (between two characters) is corresponds to a 
+     * hit (such as a mouse click) at the specified coordinates within 
+     * the specified text rectangle.
+     * 
+     * @param x the X coordinate in this TextLayout.
+     * @param y the Y coordinate in this TextLayout.
+     * @param bounds the bounds of the text area.
+     * 
+     * TextHitInfo object cooresponding to the given coordinates
+     * within the text.
+     */
+    public TextHitInfo hitTestChar(float x, float y, Rectangle2D bounds) {
+        if (x > bounds.getMaxX()) {
+            return breaker.isLTR() ?
+                    TextHitInfo.trailing(breaker.getCharCount() - 1) : TextHitInfo.leading(0);
+        }
+
+        if (x < bounds.getMinX()) {
+            return breaker.isLTR() ?
+                    TextHitInfo.leading(0) : TextHitInfo.trailing(breaker.getCharCount() - 1);
+        }
+
+        return breaker.hitTest(x, y);
+    }
+
+    /**
+     * Returns true if this TextLayout has a "left to right" 
+     * direction.
+     * 
+     * @return true if this TextLayout has a "left to right" 
+     * direction, false if this TextLayout has a "right to left" 
+     * direction. 
+     */
+    public boolean isLeftToRight() {
+        return breaker.isLTR();
+    }
+
+    /**
+     * Returns true if this TextLayout is vertical, false otherwise.
+     * 
+     * @return true if this TextLayout is vertical, false if horizontal.
+     */
+    public boolean isVertical() {
+        return false;
+    }
+}
+
diff --git a/awt/java/awt/font/TextMeasurer.java b/awt/java/awt/font/TextMeasurer.java
new file mode 100644
index 0000000..017f3d9
--- /dev/null
+++ b/awt/java/awt/font/TextMeasurer.java
@@ -0,0 +1,167 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.font;
+
+
+import java.text.AttributedCharacterIterator;
+
+import org.apache.harmony.awt.gl.font.TextMetricsCalculator;
+import org.apache.harmony.awt.gl.font.TextRunBreaker;
+
+/**
+ * The TextMeasurer class provides utilities for line break operations.
+ */
+public final class TextMeasurer implements Cloneable {
+    
+    /** The aci. */
+    AttributedCharacterIterator aci;
+    
+    /** The frc. */
+    FontRenderContext frc;
+    
+    /** The breaker. */
+    TextRunBreaker breaker = null;
+    
+    /** The tmc. */
+    TextMetricsCalculator tmc = null;
+
+    /**
+     * Instantiates a new text measurer from the specified text.
+     * 
+     * @param text the source text.
+     * @param frc the FontRenderContext.
+     */
+    public TextMeasurer(AttributedCharacterIterator text, FontRenderContext frc) {
+        this.aci = text;
+        this.frc = frc;
+        breaker = new TextRunBreaker(aci, this.frc);
+        tmc = new TextMetricsCalculator(breaker);
+    }
+
+    /**
+     * Replaces the current text with the new text, inserting a break
+     * character at the specified insert position.  
+     * 
+     * @param newParagraph the new paragraph text. 
+     * @param insertPos the position in the text where the character is inserted. 
+     */
+    public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) {
+        AttributedCharacterIterator oldAci = aci;
+        aci = newParagraph;
+        if ((oldAci.getEndIndex() - oldAci.getBeginIndex()) -
+           (aci.getEndIndex() - aci.getBeginIndex()) != -1) {
+            breaker = new TextRunBreaker(aci, this.frc);
+            tmc = new TextMetricsCalculator(breaker);
+        } else {
+            breaker.insertChar(newParagraph, insertPos);
+        }
+    }
+
+    /**
+     * Replaces the current text with the new text and deletes a
+     * character at the specified position.  
+     * 
+     * @param newParagraph the paragraph text after deletion. 
+     * @param deletePos the position in the text where the character is removed. 
+     */
+    public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) {
+        AttributedCharacterIterator oldAci = aci;
+        aci = newParagraph;
+        if ((oldAci.getEndIndex() - oldAci.getBeginIndex()) -
+           (aci.getEndIndex() - aci.getBeginIndex()) != 1) {
+            breaker = new TextRunBreaker(aci, this.frc);
+            tmc = new TextMetricsCalculator(breaker);
+        } else {
+            breaker.deleteChar(newParagraph, deletePos);
+        }
+    }
+
+    /**
+     * Returns a copy of this object.
+     * 
+     * @return a copy of this object.
+     */
+    @Override
+    protected Object clone() {
+        return new TextMeasurer((AttributedCharacterIterator) aci.clone(), frc);
+    }
+
+    /**
+     * Returns a TextLayout of the specified character range.
+     * 
+     * @param start the index of the first character.
+     * @param limit the index after the last character. 
+     * 
+     * @return a TextLayout for the characters beginning at "start" up 
+     * to "end".
+     */
+    public TextLayout getLayout(int start, int limit) {
+        breaker.pushSegments(start - aci.getBeginIndex(), limit - aci.getBeginIndex());
+
+        breaker.createAllSegments();
+        TextLayout layout = new TextLayout((TextRunBreaker) breaker.clone());
+
+        breaker.popSegments();
+        return layout;
+    }
+
+    /**
+     * Returns the graphical width of a line beginning at "start" 
+     * parameter and including characters up to "end" parameter. 
+     * "start" and "end" are absolute indices, not relative to the 
+     * "start" of the paragraph.
+     * 
+     * @param start the character index at which to start measuring.
+     * @param end the character index at which to stop measuring.
+     * 
+     * @return the graphical width of a line beginning at "start"  
+     * and including characters up to "end".
+     */
+    public float getAdvanceBetween(int start, int end) {
+        breaker.pushSegments(start - aci.getBeginIndex(), end - aci.getBeginIndex());
+
+        breaker.createAllSegments();
+        float retval = tmc.createMetrics().getAdvance();
+
+        breaker.popSegments();
+        return retval;
+    }
+
+    /**
+     * Returns the index of the first character which is not fit on 
+     * a line beginning at start and possible measuring up to maxAdvance 
+     * in graphical width.
+     * 
+     * @param start he character index at which to start measuring. 
+     * @param maxAdvance the graphical width in which the line must fit. 
+     * 
+     * @return the index after the last character that is fit on a line 
+     * beginning at start, which is not longer than maxAdvance in graphical
+     * width.
+     */
+    public int getLineBreakIndex(int start, float maxAdvance) {
+        breaker.createAllSegments();
+        return breaker.getLineBreakIndex(
+                start - aci.getBeginIndex(), maxAdvance) + aci.getBeginIndex();
+    }
+}
+
diff --git a/awt/java/awt/font/TransformAttribute.java b/awt/java/awt/font/TransformAttribute.java
new file mode 100644
index 0000000..7c9b0bd
--- /dev/null
+++ b/awt/java/awt/font/TransformAttribute.java
@@ -0,0 +1,80 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package java.awt.font;
+
+import java.awt.geom.AffineTransform;
+import java.io.Serializable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The TransformAttribute class is a wrapper for the AffineTransform class in
+ * order to use it as attribute.
+ */
+public final class TransformAttribute implements Serializable {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 3356247357827709530L;
+
+    // affine transform of this TransformAttribute instance
+    /** The transform. */
+    private AffineTransform fTransform;
+
+    /**
+     * Instantiates a new TransformAttribute from the specified
+     * AffineTransform.
+     * 
+     * @param transform the AffineTransform to be wrapped.
+     */
+    public TransformAttribute(AffineTransform transform) {
+        if (transform == null) {
+            // awt.94=transform can not be null
+            throw new IllegalArgumentException(Messages.getString("awt.94")); //$NON-NLS-1$
+        }
+        if (!transform.isIdentity()){
+            this.fTransform = new AffineTransform(transform);
+        }
+    }
+
+    /**
+     * Gets the initial AffineTransform which is wrapped.
+     * 
+     * @return the initial AffineTransform which is wrapped.
+     */
+    public AffineTransform getTransform() {
+        if (fTransform != null){
+            return new AffineTransform(fTransform);
+        }
+        return new AffineTransform();
+    }
+
+    /**
+     * Checks if this transform is an identity transform.
+     * 
+     * @return true, if this transform is an identity transform,
+     * false otherwise.
+     */
+    public boolean isIdentity() {
+        return (fTransform == null);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/AffineTransform.java b/awt/java/awt/geom/AffineTransform.java
new file mode 100644
index 0000000..5fd3934
--- /dev/null
+++ b/awt/java/awt/geom/AffineTransform.java
@@ -0,0 +1,1158 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Shape;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class AffineTransform represents a linear transformation 
+ * (rotation, scaling, or shear) followed by a translation that 
+ * acts on a coordinate space. It preserves colinearity of points 
+ * and ratios of distances between collinear points: so if A, B, 
+ * and C are on a line, then after the space has been transformed 
+ * via the affine transform, the images of the three points will 
+ * still be on a line, and the ratio of the distance from A to B
+ * with the distance from B to C will be the same as the corresponding
+ * ratio in the image space.
+ */
+public class AffineTransform implements Cloneable, Serializable {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 1330973210523860834L;
+
+    /** The Constant TYPE_IDENTITY. */
+    public static final int TYPE_IDENTITY = 0;
+    
+    /** The Constant TYPE_TRANSLATION. */
+    public static final int TYPE_TRANSLATION = 1;
+    
+    /** The Constant TYPE_UNIFORM_SCALE. */
+    public static final int TYPE_UNIFORM_SCALE = 2;
+    
+    /** The Constant TYPE_GENERAL_SCALE. */
+    public static final int TYPE_GENERAL_SCALE = 4;
+    
+    /** The Constant TYPE_QUADRANT_ROTATION. */
+    public static final int TYPE_QUADRANT_ROTATION = 8;
+    
+    /** The Constant TYPE_GENERAL_ROTATION. */
+    public static final int TYPE_GENERAL_ROTATION = 16;
+    
+    /** The Constant TYPE_GENERAL_TRANSFORM. */
+    public static final int TYPE_GENERAL_TRANSFORM = 32;
+    
+    /** The Constant TYPE_FLIP. */
+    public static final int TYPE_FLIP = 64;
+    
+    /** The Constant TYPE_MASK_SCALE. */
+    public static final int TYPE_MASK_SCALE = TYPE_UNIFORM_SCALE | TYPE_GENERAL_SCALE;
+    
+    /** The Constant TYPE_MASK_ROTATION. */
+    public static final int TYPE_MASK_ROTATION = TYPE_QUADRANT_ROTATION | TYPE_GENERAL_ROTATION;
+
+    /** The <code>TYPE_UNKNOWN</code> is an initial type value. */
+    static final int TYPE_UNKNOWN = -1;
+    
+    /** The min value equivalent to zero. If absolute value less then ZERO it considered as zero. */
+    static final double ZERO = 1E-10;
+   
+    /** The values of transformation matrix. */
+    double m00;
+    
+    /** The m10. */
+    double m10;
+    
+    /** The m01. */
+    double m01;
+    
+    /** The m11. */
+    double m11;
+    
+    /** The m02. */
+    double m02;
+    
+    /** The m12. */
+    double m12;
+
+    /** The transformation <code>type</code>. */
+    transient int type;
+
+    /**
+     * Instantiates a new affine transform of type <code>TYPE_IDENTITY</code>
+     * (which leaves coordinates unchanged).
+     */
+    public AffineTransform() {
+        type = TYPE_IDENTITY;
+        m00 = m11 = 1.0;
+        m10 = m01 = m02 = m12 = 0.0;
+    }
+
+    /**
+     * Instantiates a new affine transform that has the same data as
+     * the given AffineTransform.
+     * 
+     * @param t the transform to copy.
+     */
+    public AffineTransform(AffineTransform t) {
+        this.type = t.type;
+        this.m00 = t.m00;
+        this.m10 = t.m10;
+        this.m01 = t.m01;
+        this.m11 = t.m11;
+        this.m02 = t.m02;
+        this.m12 = t.m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by specifying the values of the 2x3
+     * transformation matrix as floats. The type is set to the default
+     * type: <code>TYPE_UNKNOWN</code>
+     * 
+     * @param m00 the m00 entry in the transformation matrix.
+     * @param m10 the m10 entry in the transformation matrix.
+     * @param m01 the m01 entry in the transformation matrix.
+     * @param m11 the m11 entry in the transformation matrix.
+     * @param m02 the m02 entry in the transformation matrix.
+     * @param m12 the m12 entry in the transformation matrix.
+     */
+    public AffineTransform(float m00, float m10, float m01, float m11, float m02, float m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by specifying the values of the 2x3
+     * transformation matrix as doubles. The type is set to the default
+     * type: <code>TYPE_UNKNOWN</code>
+     * 
+     * @param m00 the m00 entry in the transformation matrix.
+     * @param m10 the m10 entry in the transformation matrix.
+     * @param m01 the m01 entry in the transformation matrix.
+     * @param m11 the m11 entry in the transformation matrix.
+     * @param m02 the m02 entry in the transformation matrix.
+     * @param m12 the m12 entry in the transformation matrix.
+     */
+    public AffineTransform(double m00, double m10, double m01, double m11, double m02, double m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Instantiates a new affine transform by reading the values of the 
+     * transformation matrix from an array of floats. The mapping from the
+     * array to the matrix starts with <code>matrix[0]</code> giving the 
+     * top-left entry of the matrix and 
+     * proceeds with the usual left-to-right and top-down ordering.
+     * <p>
+     * If the array has only four entries, then the two entries of the 
+     * last row of the transformation matrix default to zero.
+     * 
+     * @param matrix the array of four or six floats giving the values 
+     * of the matrix.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if the size of the array
+     * is 0, 1, 2, 3, or 5.
+     */
+    public AffineTransform(float[] matrix) {
+        this.type = TYPE_UNKNOWN;
+        m00 = matrix[0];
+        m10 = matrix[1];
+        m01 = matrix[2];
+        m11 = matrix[3];
+        if (matrix.length > 4) {
+            m02 = matrix[4];
+            m12 = matrix[5];
+        }
+    }
+
+    /**
+     * Instantiates a new affine transform by reading the values of the 
+     * transformation matrix from an array of doubles. The mapping from the
+     * array to the matrix starts with <code>matrix[0]</code> giving the 
+     * top-left entry of the matrix and 
+     * proceeds with the usual left-to-right and top-down ordering.
+     * <p>
+     * If the array has only four entries, then the two entries of the 
+     * last row of the transformation matrix default to zero.
+     * 
+     * @param matrix the array of four or six doubles giving the values 
+     * of the matrix.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if the size of the array
+     * is 0, 1, 2, 3, or 5.
+     */
+    public AffineTransform(double[] matrix) {
+        this.type = TYPE_UNKNOWN;
+        m00 = matrix[0];
+        m10 = matrix[1];
+        m01 = matrix[2];
+        m11 = matrix[3];
+        if (matrix.length > 4) {
+            m02 = matrix[4];
+            m12 = matrix[5];
+        }
+    }
+
+
+    /**
+     * Returns type of the affine transformation.
+     * <p>
+     * The type is computed as follows: Label the entries of the 
+     * transformation matrix as three rows (m00, m01), (m10, m11), and
+     * (m02, m12). Then if the original basis vectors are (1, 0) and (0, 1), 
+     * the new basis vectors after transformation are given by (m00, m01) 
+     * and (m10, m11), and the translation vector is (m02, m12).
+     * <p>
+     * The types are classified as follows: <br/> 
+     *   TYPE_IDENTITY - no change<br/>
+     *   TYPE_TRANSLATION - The translation vector isn't zero<br/>
+     *   TYPE_UNIFORM_SCALE - The new basis vectors have equal length<br/>
+     *   TYPE_GENERAL_SCALE - The new basis vectors dont' have equal length<br/>
+     *   TYPE_FLIP - The new basis vector orientation differs from the original one<br/>
+     *   TYPE_QUADRANT_ROTATION - The new basis is a rotation of the original by 90, 180, 270, or 360 degrees<br/>   
+     *   TYPE_GENERAL_ROTATION - The new basis is a rotation of the original by an arbitrary angle<br/>
+     *   TYPE_GENERAL_TRANSFORM - The transformation can't be inverted.<br/>
+     *   <p>
+     * Note that multiple types are possible, thus the types can be combined 
+     * using bitwise combinations.
+     * 
+     * @return the type of the Affine Transform.
+     */
+    public int getType() {
+        if (type != TYPE_UNKNOWN) {
+            return type;
+        }
+
+        int type = 0;
+
+        if (m00 * m01 + m10 * m11 != 0.0) {
+            type |= TYPE_GENERAL_TRANSFORM;
+            return type;
+        }
+
+        if (m02 != 0.0 || m12 != 0.0) {
+            type |= TYPE_TRANSLATION;
+        } else
+            if (m00 == 1.0 && m11 == 1.0 && m01 == 0.0 && m10 == 0.0) {
+                type = TYPE_IDENTITY;
+                return type;
+            }
+
+        if (m00 * m11 - m01 * m10 < 0.0) {
+            type |= TYPE_FLIP;
+        }
+
+        double dx = m00 * m00 + m10 * m10;
+        double dy = m01 * m01 + m11 * m11;
+        if (dx != dy) {
+            type |= TYPE_GENERAL_SCALE;
+        } else
+            if (dx != 1.0) {
+                type |= TYPE_UNIFORM_SCALE;
+            }
+
+        if ((m00 == 0.0 && m11 == 0.0) ||
+            (m10 == 0.0 && m01 == 0.0 && (m00 < 0.0 || m11 < 0.0)))
+        {
+            type |= TYPE_QUADRANT_ROTATION;
+        } else
+            if (m01 != 0.0 || m10 != 0.0) {
+                type |= TYPE_GENERAL_ROTATION;
+            }
+
+        return type;
+    }
+
+    /**
+     * Gets the scale x entry of the transformation matrix
+     * (the upper left matrix entry).
+     * 
+     * @return the scale x value.
+     */
+    public double getScaleX() {
+        return m00;
+    }
+
+    /**
+     * Gets the scale y entry of the transformation matrix
+     * (the lower right entry of the linear transformation).
+     * 
+     * @return the scale y value.
+     */
+    public double getScaleY() {
+        return m11;
+    }
+
+    /**
+     * Gets the shear x entry of the transformation matrix
+     * (the upper right entry of the linear transformation).
+     * 
+     * @return the shear x value.
+     */
+    public double getShearX() {
+        return m01;
+    }
+
+    /**
+     * Gets the shear y entry of the transformation matrix
+     * (the lower left entry of the linear transformation).
+     * 
+     * @return the shear y value.
+     */
+    public double getShearY() {
+        return m10;
+    }
+
+    /**
+     * Gets the x coordinate of the translation vector.
+     * 
+     * @return the x coordinate of the translation vector.
+     */
+    public double getTranslateX() {
+        return m02;
+    }
+
+    /**
+     * Gets the y coordinate of the translation vector.
+     * 
+     * @return the y coordinate of the translation vector.
+     */
+    public double getTranslateY() {
+        return m12;
+    }
+
+    /**
+     * Checks if the AffineTransformation is the identity.
+     * 
+     * @return true, if the AffineTransformation is the identity.
+     */
+    public boolean isIdentity() {
+        return getType() == TYPE_IDENTITY;
+    }
+
+    /**
+     * Writes the values of the transformation matrix into the given 
+     * array of doubles. If the array has length 4, only the linear
+     * transformation part will be written into it. If it has length 
+     * greater than 4, the translation vector will be included as well.
+     * 
+     * @param matrix the array to fill with the values of the matrix.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if the size of the array
+     * is 0, 1, 2, 3, or 5.
+     */
+    public void getMatrix(double[] matrix) {
+        matrix[0] = m00;
+        matrix[1] = m10;
+        matrix[2] = m01;
+        matrix[3] = m11;
+        if (matrix.length > 4) {
+            matrix[4] = m02;
+            matrix[5] = m12;
+        }
+    }
+
+    /**
+     * Gets the determinant of the linear transformation matrix.
+     * 
+     * @return the determinant of the linear transformation matrix.
+     */
+    public double getDeterminant() {
+        return m00 * m11 - m01 * m10;
+    }
+
+    /**
+     * Sets the transform in terms of a list of double values.
+     * 
+     * @param m00 the m00 coordinate of the transformation matrix.
+     * @param m10 the m10 coordinate of the transformation matrix.
+     * @param m01 the m01 coordinate of the transformation matrix.
+     * @param m11 the m11 coordinate of the transformation matrix.
+     * @param m02 the m02 coordinate of the transformation matrix.
+     * @param m12 the m12 coordinate of the transformation matrix.
+     */
+    public void setTransform(double m00, double m10, double m01, double m11, double m02, double m12) {
+        this.type = TYPE_UNKNOWN;
+        this.m00 = m00;
+        this.m10 = m10;
+        this.m01 = m01;
+        this.m11 = m11;
+        this.m02 = m02;
+        this.m12 = m12;
+    }
+
+    /**
+     * Sets the transform's data to match the data of the transform 
+     * sent as a parameter.
+     * 
+     * @param t the transform that gives the new values.
+     */
+    public void setTransform(AffineTransform t) {
+        type = t.type;
+        setTransform(t.m00, t.m10, t.m01, t.m11, t.m02, t.m12);
+    }
+
+    /**
+     * Sets the transform to the identity transform.
+     */
+    public void setToIdentity() {
+        type = TYPE_IDENTITY;
+        m00 = m11 = 1.0;
+        m10 = m01 = m02 = m12 = 0.0;
+    }
+
+    /**
+     * Sets the transformation to a translation alone.
+     * Sets the linear part of the transformation to identity 
+     * and the translation vector to the values sent as parameters.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_TRANSLATION</code>.
+     * 
+     * @param mx the distance to translate in the x direction.
+     * @param my the distance to translate in the y direction.
+     */
+    public void setToTranslation(double mx, double my) {
+        m00 = m11 = 1.0;
+        m01 = m10 = 0.0;
+        m02 = mx;
+        m12 = my;
+        if (mx == 0.0 && my == 0.0) {
+            type = TYPE_IDENTITY;
+        } else {
+            type = TYPE_TRANSLATION;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a scale alone, eliminating 
+     * rotation, shear, and translation elements.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param scx the scaling factor in the x direction.
+     * @param scy the scaling factor in the y direction.
+     */
+    public void setToScale(double scx, double scy) {
+        m00 = scx;
+        m11 = scy;
+        m10 = m01 = m02 = m12 = 0.0;
+        if (scx != 1.0 || scy != 1.0) {
+            type = TYPE_UNKNOWN;
+        } else {
+            type = TYPE_IDENTITY;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a shear alone, eliminating 
+     * rotation, scaling, and translation elements.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param shx the shearing factor in the x direction.
+     * @param shy the shearing factor in the y direction.
+     */
+    public void setToShear(double shx, double shy) {
+        m00 = m11 = 1.0;
+        m02 = m12 = 0.0;
+        m01 = shx;
+        m10 = shy;
+        if (shx != 0.0 || shy != 0.0) {
+            type = TYPE_UNKNOWN;
+        } else {
+            type = TYPE_IDENTITY;
+        }
+    }
+
+    /**
+     * Sets the transformation to being a rotation alone, eliminating 
+     * shearing, scaling, and translation elements.
+     * Sets the type to <code>TYPE_IDENTITY</code>
+     * if the resulting AffineTransformation is the identity 
+     * transformation, otherwise sets it to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     */
+    public void setToRotation(double angle) {
+        double sin = Math.sin(angle);
+        double cos = Math.cos(angle);
+        if (Math.abs(cos) < ZERO) {
+            cos = 0.0;
+            sin = sin > 0.0 ? 1.0 : -1.0;
+        } else
+            if (Math.abs(sin) < ZERO) {
+                sin = 0.0;
+                cos = cos > 0.0 ? 1.0 : -1.0;
+            }
+        m00 = m11 = cos;
+        m01 = -sin;
+        m10 = sin;
+        m02 = m12 = 0.0;
+        type = TYPE_UNKNOWN;
+    }
+
+    /**
+     * Sets the transformation to being a rotation followed by a 
+     * translation. 
+     * Sets the type to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     * @param px the distance to translate in the x direction.
+     * @param py the distance to translate in the y direction.
+     */
+    public void setToRotation(double angle, double px, double py) {
+        setToRotation(angle);
+        m02 = px * (1.0 - m00) + py * m10;
+        m12 = py * (1.0 - m00) - px * m10;
+        type = TYPE_UNKNOWN;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a translation alone
+     * with the translation vector given by the values sent as parameters.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_TRANSLATION</code>.
+     * 
+     * @param mx the distance to translate in the x direction.
+     * @param my the distance to translate in the y direction.
+
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getTranslateInstance(double mx, double my) {
+        AffineTransform t = new AffineTransform();
+        t.setToTranslation(mx, my);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a scale alone.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param scx the scaling factor in the x direction.
+     * @param scY the scaling factor in the y direction.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getScaleInstance(double scx, double scY) {
+        AffineTransform t = new AffineTransform();
+        t.setToScale(scx, scY);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a shear alone.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param shx the shearing factor in the x direction.
+     * @param shy the shearing factor in the y direction.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getShearInstance(double shx, double shy) {
+        AffineTransform m = new AffineTransform();
+        m.setToShear(shx, shy);
+        return m;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a rotation alone.
+     * The new transformation's type is <code>TYPE_IDENTITY</code>
+     * if the AffineTransformation is the identity 
+     * transformation, otherwise it's <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getRotateInstance(double angle) {
+        AffineTransform t = new AffineTransform();
+        t.setToRotation(angle);
+        return t;
+    }
+
+    /**
+     * Creates a new AffineTransformation that is a rotation followed by a 
+     * translation. 
+     * Sets the type to <code>TYPE_UNKNOWN</code>.
+     * 
+     * @param angle the angle of rotation in radians.
+     * @param x the distance to translate in the x direction.
+     * @param y the distance to translate in the y direction.
+     * 
+     * @return the new AffineTransformation.
+     */
+    public static AffineTransform getRotateInstance(double angle, double x, double y) {
+        AffineTransform t = new AffineTransform();
+        t.setToRotation(angle, x, y);
+        return t;
+    }
+
+    /**
+     * Applies a translation to this AffineTransformation.
+     * 
+     * @param mx the distance to translate in the x direction.
+     * @param my the distance to translate in the y direction.
+     */
+    public void translate(double mx, double my) {
+        concatenate(AffineTransform.getTranslateInstance(mx, my));
+    }
+
+    /**
+     * Applies a scaling transformation to this AffineTransformation.
+     * 
+     * @param scx the scaling factor in the x direction.
+     * @param scy the scaling factor in the y direction.
+     */
+    public void scale(double scx, double scy) {
+        concatenate(AffineTransform.getScaleInstance(scx, scy));
+    }
+
+    /**
+     * Applies a shearing transformation to this AffineTransformation.
+     * 
+     * @param shx the shearing factor in the x direction.
+     * @param shy the shearing factor in the y direction.
+     */
+    public void shear(double shx, double shy) {
+        concatenate(AffineTransform.getShearInstance(shx, shy));
+    }
+
+    /**
+     * Applies a rotation transformation to this AffineTransformation.
+     * 
+     * @param angle the angle of rotation in radians.
+     */
+    public void rotate(double angle) {
+        concatenate(AffineTransform.getRotateInstance(angle));
+    }
+
+    /**
+     * Applies a rotation and translation transformation to this 
+     * AffineTransformation.
+     * 
+     * @param angle the angle of rotation in radians.
+     * @param px the distance to translate in the x direction.
+     * @param py the distance to translate in the y direction.
+     */
+    public void rotate(double angle, double px, double py) {
+        concatenate(AffineTransform.getRotateInstance(angle, px, py));
+    }
+
+    /**
+     * Multiplies the matrix representations of two AffineTransform objects.
+     * 
+     * @param t1 - the AffineTransform object is a multiplicand
+     * @param t2 - the AffineTransform object is a multiplier
+     * 
+     * @return an AffineTransform object that is the result of t1 multiplied by the matrix t2.
+     */
+    AffineTransform multiply(AffineTransform t1, AffineTransform t2) {
+        return new AffineTransform(
+                t1.m00 * t2.m00 + t1.m10 * t2.m01,          // m00
+                t1.m00 * t2.m10 + t1.m10 * t2.m11,          // m01
+                t1.m01 * t2.m00 + t1.m11 * t2.m01,          // m10
+                t1.m01 * t2.m10 + t1.m11 * t2.m11,          // m11
+                t1.m02 * t2.m00 + t1.m12 * t2.m01 + t2.m02, // m02
+                t1.m02 * t2.m10 + t1.m12 * t2.m11 + t2.m12);// m12
+    }
+
+    /**
+     * Applies the given AffineTransform to this AffineTransform
+     * via matrix multiplication.
+     * 
+     * @param t the AffineTransform to apply to this AffineTransform.
+     */
+    public void concatenate(AffineTransform t) {
+        setTransform(multiply(t, this));
+    }
+
+    /**
+     * Changes the current AffineTransform the one obtained by 
+     * taking the transform t and applying this AffineTransform to it.
+     * 
+     * @param t the AffineTransform that this AffineTransform is multiplied by.
+     */
+    public void preConcatenate(AffineTransform t) {
+        setTransform(multiply(this, t));
+    }
+
+    /**
+     * Creates an AffineTransform that is the inverse of this transform.
+     * 
+     * @return the affine transform that is the inverse of this AffineTransform.
+     * 
+     * @throws NoninvertibleTransformException if this AffineTransform cannot be 
+     * inverted (the determinant of the linear transformation part is zero).
+     */
+    public AffineTransform createInverse() throws NoninvertibleTransformException {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+        return new AffineTransform(
+                 m11 / det, // m00
+                -m10 / det, // m10
+                -m01 / det, // m01
+                 m00 / det, // m11
+                (m01 * m12 - m11 * m02) / det, // m02
+                (m10 * m02 - m00 * m12) / det  // m12
+        );
+    }
+
+    /**
+     * Apply the current AffineTransform to the point.
+     * 
+     * @param src the original point.
+     * @param dst Point2D object to be filled with the destination
+     * coordinates (where the original point is sent by this AffineTransform). May be null.
+     * 
+     * @return the point in the AffineTransform's image space where the
+     * original point is sent.
+     */
+    public Point2D transform(Point2D src, Point2D dst) {
+        if (dst == null) {
+            if (src instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX();
+        double y = src.getY();
+
+        dst.setLocation(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12);
+        return dst;
+    }
+
+    /**
+     * Applies this AffineTransform to an array of points.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length > src.length</code> or
+     * <code>dstOff + length > dst.length</code>.
+     */
+    public void transform(Point2D[] src, int srcOff, Point2D[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            Point2D srcPoint = src[srcOff++]; 
+            double x = srcPoint.getX();
+            double y = srcPoint.getY();
+            Point2D dstPoint = dst[dstOff]; 
+            if (dstPoint == null) {
+                if (srcPoint instanceof Point2D.Double) {
+                    dstPoint = new Point2D.Double();
+                } else {
+                    dstPoint = new Point2D.Float();
+                }
+            }
+            dstPoint.setLocation(x * m00 + y * m01 + m02, x * m10 + y * m11 + m12);
+            dst[dstOff++] = dstPoint;
+        }
+    }
+    
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+     public void transform(double[] src, int srcOff, double[] dst, int dstOff, int length) {
+        int step = 2;
+        if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) {
+            srcOff = srcOff + length * 2 - 2;
+            dstOff = dstOff + length * 2 - 2;
+            step = -2;
+        }
+        while (--length >= 0) {
+            double x = src[srcOff + 0];
+            double y = src[srcOff + 1];
+            dst[dstOff + 0] = x * m00 + y * m01 + m02;
+            dst[dstOff + 1] = x * m10 + y * m11 + m12;
+            srcOff += step;
+            dstOff += step;
+        }
+    }
+
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of float values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(float[] src, int srcOff, float[] dst, int dstOff, int length) {
+        int step = 2;
+        if (src == dst && srcOff < dstOff && dstOff < srcOff + length * 2) {
+            srcOff = srcOff + length * 2 - 2;
+            dstOff = dstOff + length * 2 - 2;
+            step = -2;
+        }
+        while (--length >= 0) {
+            float x = src[srcOff + 0];
+            float y = src[srcOff + 1];
+            dst[dstOff + 0] = (float)(x * m00 + y * m01 + m02);
+            dst[dstOff + 1] = (float)(x * m10 + y * m11 + m12);
+            srcOff += step;
+            dstOff += step;
+        }
+    }
+    
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of float values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * The destination coordinates are given as values of type <code>double</code>.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(float[] src, int srcOff, double[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            float x = src[srcOff++];
+            float y = src[srcOff++];
+            dst[dstOff++] = x * m00 + y * m01 + m02;
+            dst[dstOff++] = x * m10 + y * m11 + m12;
+        }
+    }
+
+    /**
+     * Applies this AffineTransform to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * The destination coordinates are given as values of type <code>float</code>.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void transform(double[] src, int srcOff, float[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            double x = src[srcOff++];
+            double y = src[srcOff++];
+            dst[dstOff++] = (float)(x * m00 + y * m01 + m02);
+            dst[dstOff++] = (float)(x * m10 + y * m11 + m12);
+        }
+    }
+
+    /**
+     * Transforms the point according to the linear transformation
+     * part of this AffineTransformation (without applying the translation).
+     * 
+     * @param src the original point.
+     * @param dst the point object where the result of the delta transform
+     * is written.
+     * 
+     * @return the result of applying the delta transform (linear part 
+     * only) to the original point.
+     */
+    // TODO: is this right? if dst is null, we check what it's an
+    // instance of? Shouldn't it be src instanceof Point2D.Double?
+    public Point2D deltaTransform(Point2D src, Point2D dst) {
+        if (dst == null) {
+            if (dst instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX();
+        double y = src.getY();
+
+        dst.setLocation(x * m00 + y * m01, x * m10 + y * m11);
+        return dst;
+    }
+
+    /**
+     * Applies the linear transformation part of this AffineTransform 
+     * (ignoring the translation part) to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the delta transformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     */
+    public void deltaTransform(double[] src, int srcOff, double[] dst, int dstOff, int length) {
+        while (--length >= 0) {
+            double x = src[srcOff++];
+            double y = src[srcOff++];
+            dst[dstOff++] = x * m00 + y * m01;
+            dst[dstOff++] = x * m10 + y * m11;
+        }
+    }
+
+    /**
+     * Transforms the point according to the inverse of this AffineTransformation.
+     * 
+     * @param src the original point.
+     * @param dst the point object where the result of the inverse transform
+     * is written (may be null).
+     * 
+     * @return the result of applying the inverse transform.
+     * Inverse transform.
+     * 
+     * @throws NoninvertibleTransformException if this AffineTransform cannot be 
+     * inverted (the determinant of the linear transformation part is zero).
+     */
+    public Point2D inverseTransform(Point2D src, Point2D dst) throws NoninvertibleTransformException {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            if (src instanceof Point2D.Double) {
+                dst = new Point2D.Double();
+            } else {
+                dst = new Point2D.Float();
+            }
+        }
+
+        double x = src.getX() - m02;
+        double y = src.getY() - m12;
+
+        dst.setLocation((x * m11 - y * m01) / det, (y * m00 - x * m10) / det);
+        return dst;
+    }
+
+    /**
+     * Applies the inverse of this AffineTransform to a set of points given 
+     * as an array of double values where every two values in the array 
+     * give the coordinates of a point; the even-indexed values giving the
+     * x coordinates and the odd-indexed values giving the y coordinates.
+     * 
+     * @param src the array of points to be transformed.
+     * @param srcOff the offset in the source point array of the first point
+     * to be transformed.
+     * @param dst the point array where the images of the points (after 
+     * applying the inverse of the AffineTransformation) should be placed.
+     * @param dstOff the offset in the destination array where the new 
+     * values should be written.
+     * @param length the number of points to transform.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if 
+     * <code>srcOff + length*2 > src.length</code> or
+     * <code>dstOff + length*2 > dst.length</code>.
+     * @throws NoninvertibleTransformException if this AffineTransform cannot be 
+     * inverted (the determinant of the linear transformation part is zero).
+     */
+    public void inverseTransform(double[] src, int srcOff, double[] dst, int dstOff, int length)
+        throws NoninvertibleTransformException
+    {
+        double det = getDeterminant();
+        if (Math.abs(det) < ZERO) {
+            // awt.204=Determinant is zero
+            throw new NoninvertibleTransformException(Messages.getString("awt.204")); //$NON-NLS-1$
+        }
+
+        while (--length >= 0) {
+            double x = src[srcOff++] - m02;
+            double y = src[srcOff++] - m12;
+            dst[dstOff++] = (x * m11 - y * m01) / det;
+            dst[dstOff++] = (y * m00 - x * m10) / det;
+        }
+    }
+
+    /**
+     * Creates a new shape whose data is given by applying this 
+     * AffineTransform to the specified shape.
+     * 
+     * @param src the original shape whose data is to be transformed.
+     * 
+     * @return the new shape found by applying this AffineTransform to 
+     * the original shape.
+     */
+    public Shape createTransformedShape(Shape src) {
+        if (src == null) {
+            return null;
+        }
+        if (src instanceof GeneralPath) {
+            return ((GeneralPath)src).createTransformedShape(this);
+        }
+        PathIterator path = src.getPathIterator(this);
+        GeneralPath dst = new GeneralPath(path.getWindingRule());
+        dst.append(path, false);
+        return dst;
+    }
+
+    @Override
+    public String toString() {
+        return
+            getClass().getName() +
+            "[[" + m00 + ", " + m01 + ", " + m02 + "], [" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                + m10 + ", " + m11 + ", " + m12 + "]]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(m00);
+        hash.append(m01);
+        hash.append(m02);
+        hash.append(m10);
+        hash.append(m11);
+        hash.append(m12);
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof AffineTransform) {
+            AffineTransform t = (AffineTransform)obj;
+            return
+                m00 == t.m00 && m01 == t.m01 &&
+                m02 == t.m02 && m10 == t.m10 &&
+                m11 == t.m11 && m12 == t.m12;
+        }
+        return false;
+    }
+
+    
+    /**
+     * Writes the AffineTrassform object to the output steam.
+     * 
+     * @param stream - the output stream
+     * 
+     * @throws IOException - if there are I/O errors while writing to the output strem
+     */
+    private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
+        stream.defaultWriteObject();
+    }
+
+    
+    /**
+     * Read the AffineTransform object from the input stream.
+     * 
+     * @param stream - the input steam
+     * 
+     * @throws IOException - if there are I/O errors while reading from the input strem
+     * @throws ClassNotFoundException - if class could not be found
+     */
+    private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+        type = TYPE_UNKNOWN;
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Arc2D.java b/awt/java/awt/geom/Arc2D.java
new file mode 100644
index 0000000..bc1e95c
--- /dev/null
+++ b/awt/java/awt/geom/Arc2D.java
@@ -0,0 +1,1028 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Arc2D represents a segment of a curve inscribed 
+ * in a rectangle. The curve is defined by a start angle and an 
+ * extent angle (the end angle minus the start angle) as 
+ * a pie wedge whose point is in the center of the rectangle.
+ * The Arc2D as a shape may be either OPEN (including nothing 
+ * but the curved arc segment itself), CHORD (the curved arc
+ * segment closed by a connecting segment from the end to the 
+ * beginning of the arc, or PIE (the segments from the end 
+ * of the arc to the center of the rectangle and from the
+ * center of the rectangle back to the arc's start point are 
+ * included).
+ */
+public abstract class Arc2D extends RectangularShape {
+
+    /** The arc type OPEN indicates that the shape includes only the 
+     * curved arc segment. */
+    public final static int OPEN = 0;
+    
+    /** The arc type CHORD indicates that as a shape the connecting
+     * segment from the end point of the curved arc to the beginning
+     * point is included. */
+    public final static int CHORD = 1;
+    
+    /** The arc type PIE indicates that as a shape the two segments 
+     * from the arc's endpoint to the center of the rectangle and from 
+     * the center of the rectangle to the arc's endpoint are included. */
+    public final static int PIE = 2;
+
+    /**
+     * The Class Float is a subclass of Arc2D in which all of the 
+     * data values are given as floats.
+     * @see Arc2D.Double
+     */
+    public static class Float extends Arc2D {
+
+        /** The x coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public float x;
+        
+        /** The y coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public float y;
+        
+        /** The width of the rectangle that contains the arc. */
+        public float width;
+        
+        /** The height of the rectangle that contains the arc. */
+        public float height;
+        
+        /** The start angle of the arc in degrees. */
+        public float start;
+        
+        /** The width angle of the arc in degrees. */
+        public float extent;
+
+        /**
+         * Instantiates a new Arc2D of type OPEN with float values.
+         */
+        public Float() {
+            super(OPEN);
+        }
+
+        /**
+         * Instantiates a new Arc2D of the specified type with float values.
+         * 
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(int type) {
+            super(type);
+        }
+
+        /**
+         * Instantiates a Arc2D with the specified float-valued data.
+         * 
+         * @param x the x coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param y the y coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param width the width of the rectangle that
+         * contains the arc.
+         * @param height the height of the rectangle that
+         * contains the arc.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(float x, float y, float width, float height, float start, float extent, int type) {
+            super(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        /**
+         * Instantiates a new Angle2D with the specified float-valued data
+         * and the bounding rectangle given by the parameter bounds.
+         * 
+         * @param bounds the bounding rectangle of the Angle2D.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Float(Rectangle2D bounds, float start, float extent, int type) {
+            super(type);
+            this.x = (float)bounds.getX();
+            this.y = (float)bounds.getY();
+            this.width = (float)bounds.getWidth();
+            this.height = (float)bounds.getHeight();
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+       @Override
+       public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getAngleStart() {
+            return start;
+        }
+
+        @Override
+        public double getAngleExtent() {
+            return extent;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        @Override
+        public void setArc(double x, double y, double width, double height,
+                double start, double extent, int type)
+        {
+            this.setArcType(type);
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+            this.start = (float)start;
+            this.extent = (float)extent;
+        }
+
+        @Override
+        public void setAngleStart(double start) {
+            this.start = (float)start;
+        }
+
+        @Override
+        public void setAngleExtent(double extent) {
+            this.extent = (float)extent;
+        }
+
+        @Override
+        protected Rectangle2D makeBounds(double x, double y, double width, double height) {
+            return new Rectangle2D.Float((float)x, (float)y, (float)width, (float)height);
+        }
+
+    }
+
+    /**
+     * The Class Double is a subclass of Arc2D in which all of the 
+     * data values are given as doubles.
+     * @see Arc2D.Float
+     */
+    public static class Double extends Arc2D {
+
+        /** The x coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public double x;
+        
+        /** The y coordinate of the upper left corner of the rectangle that
+         * contains the arc. */
+        public double y;
+        
+        /** The width of the rectangle that contains the arc. */
+        public double width;
+        
+        /** The height of the rectangle that contains the arc. */
+        public double height;
+        
+        /** The start angle of the arc in degrees. */
+        public double start;
+        
+        /** The width angle of the arc in degrees. */
+        public double extent;
+
+        /**
+         * Instantiates a new Arc2D of type OPEN with double values.
+         */
+        public Double() {
+            super(OPEN);
+        }
+
+        /**
+         * Instantiates a new Arc2D of the specified type with double values.
+         * 
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(int type) {
+            super(type);
+        }
+
+        /**
+         * Instantiates a Arc2D with the specified double-valued data.
+         * 
+         * @param x the x coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param y the y coordinate of the upper left corner of the rectangle that
+         * contains the arc.
+         * @param width the width of the rectangle that
+         * contains the arc.
+         * @param height the height of the rectangle that
+         * contains the arc.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(double x, double y, double width, double height,
+                double start, double extent, int type)
+        {
+            super(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        /**
+         * Instantiates a new Angle2D with the specified float-valued data
+         * and the bounding rectangle given by the parameter bounds.
+         * 
+         * @param bounds the bounding rectangle of the Angle2D.
+         * @param start the start angle of the arc in degrees.
+         * @param extent the width angle of the arc in degrees.
+         * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+         * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+         */
+        public Double(Rectangle2D bounds, double start, double extent, int type) {
+            super(type);
+            this.x = bounds.getX();
+            this.y = bounds.getY();
+            this.width = bounds.getWidth();
+            this.height = bounds.getHeight();
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getAngleStart() {
+            return start;
+        }
+
+        @Override
+        public double getAngleExtent() {
+            return extent;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setArc(double x, double y, double width, double height,
+                double start, double extent, int type)
+        {
+            this.setArcType(type);
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.start = start;
+            this.extent = extent;
+        }
+
+        @Override
+        public void setAngleStart(double start) {
+            this.start = start;
+        }
+
+        @Override
+        public void setAngleExtent(double extent) {
+            this.extent = extent;
+        }
+
+        @Override
+        protected Rectangle2D makeBounds(double x, double y, double width, double height) {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+
+    }
+
+    /**
+     * The Class Iterator is the subclass of PathIterator that is used to 
+     * traverse the boundary of a shape of type Arc2D.
+     */
+    class Iterator implements PathIterator {
+
+        /** The x coordinate of the center of the arc's bounding rectangle. */
+        double x;
+
+        /** The y coordinate of the center of the arc's bounding rectangle. */
+        double y;
+
+        /** Half of the width of the arc's bounding rectangle (the radius in the case of a circular arc). */
+        double width;
+        
+        /** Half of the height of the arc's bounding rectangle (the radius in the case of a circular arc). */
+        double height;
+        
+        /** The start angle of the arc in degrees. */
+        double angle;
+        
+        /** The angle extent in degrees. */
+        double extent;
+         
+        /** The closure type of the arc. */
+        int type;
+        
+        /** The path iterator transformation. */
+        AffineTransform t;
+        
+        /** The current segment index. */
+        int index;
+        
+        /** The number of arc segments the source arc subdivided to be approximated by Bezier curves. Depends on extent value. */
+        int arcCount;
+        
+        /** The number of line segments. Depends on closure type. */
+        int lineCount;
+        
+        /** The step to calculate next arc subdivision point. */
+        double step;
+        
+        /** The temporary value of cosinus of the current angle. */
+        double cos;
+
+        /** The temporary value of sinus of the current angle. */
+        double sin;
+        
+        /** The coefficient to calculate control points of Bezier curves. */
+        double k;
+        
+        /** The temporary value of x coordinate of the Bezier curve control vector. */
+        double kx;
+
+        /** The temporary value of y coordinate of the Bezier curve control vector. */
+        double ky;
+        
+        /** The x coordinate of the first path point (MOVE_TO). */
+        double mx;
+        
+        /** The y coordinate of the first path point (MOVE_TO). */
+        double my;
+
+        /**
+         * Constructs a new Arc2D.Iterator for given line and transformation
+         * 
+         * @param a - the source Arc2D object
+         * @param t the AffineTransformation.
+         */
+        Iterator(Arc2D a, AffineTransform t) {
+            if (width < 0 || height < 0) {
+                arcCount = 0;
+                lineCount = 0;
+                index = 1;
+                return;
+            }
+
+            this.width = a.getWidth() / 2.0;
+            this.height = a.getHeight() / 2.0;
+            this.x = a.getX() + width;
+            this.y = a.getY() + height;
+            this.angle = -Math.toRadians(a.getAngleStart());
+            this.extent = -a.getAngleExtent();
+            this.type = a.getArcType();
+            this.t = t;
+
+            if (Math.abs(extent) >= 360.0) {
+                arcCount = 4;
+                k = 4.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+                step = Math.PI / 2.0;
+                if (extent < 0.0) {
+                    step = -step;
+                    k = -k;
+                }
+            } else {
+                arcCount = (int)Math.rint(Math.abs(extent) / 90.0);
+                step = Math.toRadians(extent / arcCount);
+                k = 4.0 / 3.0 * (1.0 - Math.cos(step / 2.0))
+                        / Math.sin(step / 2.0);
+            }
+
+            lineCount = 0;
+            if (type == Arc2D.CHORD) {
+                lineCount++;
+            } else if (type == Arc2D.PIE) {
+                lineCount += 2;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > arcCount + lineCount;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[0] = mx = x + cos * width;
+                coords[1] = my = y + sin * height;
+            } else if (index <= arcCount) {
+                type = SEG_CUBICTO;
+                count = 3;
+                coords[0] = mx - kx;
+                coords[1] = my + ky;
+                angle += step;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[4] = mx = x + cos * width;
+                coords[5] = my = y + sin * height;
+                coords[2] = mx + kx;
+                coords[3] = my - ky;
+            } else if (index == arcCount + lineCount) {
+                type = SEG_CLOSE;
+                count = 0;
+            } else {
+                type = SEG_LINETO;
+                count = 1;
+                coords[0] = x;
+                coords[1] = y;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[0] = (float)(mx = x + cos * width);
+                coords[1] = (float)(my = y + sin * height);
+            } else if (index <= arcCount) {
+                type = SEG_CUBICTO;
+                count = 3;
+                coords[0] = (float)(mx - kx);
+                coords[1] = (float)(my + ky);
+                angle += step;
+                cos = Math.cos(angle);
+                sin = Math.sin(angle);
+                kx = k * width * sin;
+                ky = k * height * cos;
+                coords[4] = (float)(mx = x + cos * width);
+                coords[5] = (float)(my = y + sin * height);
+                coords[2] = (float)(mx + kx);
+                coords[3] = (float)(my - ky);
+            } else if (index == arcCount + lineCount) {
+                type = SEG_CLOSE;
+                count = 0;
+            } else {
+                type = SEG_LINETO;
+                count = 1;
+                coords[0] = (float)x;
+                coords[1] = (float)y;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /** The closure type of the arc. */
+    private int type;
+
+    /**
+     * Instantiates a new arc2D.
+     * 
+     * @param type the closure type.
+     */
+    protected Arc2D(int type) {
+        setArcType(type);
+    }
+
+    /**
+     * Takes the double-valued data and creates the corresponding Rectangle2D
+     * object with values either of type float or of type double depending on
+     * whether this Arc2D instance is of type Float or Double.
+     * 
+     * @param x the x coordinate of the upper left corner of the bounding rectangle.
+     * @param y the y coordinate of the upper left corner of the bounding rectangle.
+     * @param width the width of the bounding rectangle.
+     * @param height the height of the bounding rectangle.
+     * 
+     * @return the corresponding Rectangle2D object.
+     */
+    protected abstract Rectangle2D makeBounds(double x, double y, double width, double height);
+
+    /**
+     * Gets the start angle.
+     * 
+     * @return the start angle.
+     */
+    public abstract double getAngleStart();
+
+    /**
+     * Gets the width angle.
+     * 
+     * @return the width angle.
+     */
+    public abstract double getAngleExtent();
+
+    /**
+     * Sets the start angle.
+     * 
+     * @param start the new start angle.
+     */
+    public abstract void setAngleStart(double start);
+
+    /**
+     * Sets the width angle.
+     * 
+     * @param extent the new width angle.
+     */
+    public abstract void setAngleExtent(double extent);
+
+    /**
+     * Sets the data values that define the arc.
+     * 
+     * @param x the x coordinate of the upper left corner of the rectangle that
+     * contains the arc.
+     * @param y the y coordinate of the upper left corner of the rectangle that
+     * contains the arc.
+     * @param width the width of the rectangle that
+     * contains the arc.
+     * @param height the height of the rectangle that
+     * contains the arc.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the width angle of the arc in degrees.
+     * @param type the type of the new Arc2D, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public abstract void setArc(double x, double y, double width,
+            double height, double start, double extent, int type);
+
+    /**
+     * Gets the arc type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     * 
+     * @return the arc type.
+     */
+    public int getArcType() {
+        return type;
+    }
+
+    /**
+     * Sets the arc type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     * 
+     * @param type the new arc type.
+     */
+    public void setArcType(int type) {
+        if (type != OPEN && type != CHORD && type != PIE) {
+            // awt.205=Invalid type of Arc: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.205", type)); //$NON-NLS-1$
+        }
+        this.type = type;
+    }
+
+    /**
+     * Gets the start point of the arc as a Point2D.
+     * 
+     * @return the start point of the curved arc segment.
+     */
+    public Point2D getStartPoint() {
+        double a = Math.toRadians(getAngleStart());
+        return new Point2D.Double(
+                getX() + (1.0 + Math.cos(a)) * getWidth() / 2.0,
+                getY() + (1.0 - Math.sin(a)) * getHeight() / 2.0);
+    }
+
+    /**
+     * Gets the end point of the arc as a Point2D.
+     * 
+     * @return the end point of the curved arc segment.
+     */
+    public Point2D getEndPoint() {
+        double a = Math.toRadians(getAngleStart() + getAngleExtent());
+        return new Point2D.Double(
+                getX() + (1.0 + Math.cos(a)) * getWidth() / 2.0,
+                getY() + (1.0 - Math.sin(a)) * getHeight() / 2.0);
+    }
+
+    public Rectangle2D getBounds2D() {
+        if (isEmpty()) {
+            return makeBounds(getX(), getY(), getWidth(), getHeight());
+        }
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+
+        double bx1 = containsAngle(180.0) ? rx1 : Math.min(p1.getX(), p2.getX());
+        double by1 = containsAngle(90.0)  ? ry1 : Math.min(p1.getY(), p2.getY());
+        double bx2 = containsAngle(0.0)   ? rx2 : Math.max(p1.getX(), p2.getX());
+        double by2 = containsAngle(270.0) ? ry2 : Math.max(p1.getY(), p2.getY());
+
+        if (type == PIE) {
+            double cx = getCenterX();
+            double cy = getCenterY();
+            bx1 = Math.min(bx1, cx);
+            by1 = Math.min(by1, cy);
+            bx2 = Math.max(bx2, cx);
+            by2 = Math.max(by2, cy);
+        }
+        return makeBounds(bx1, by1, bx2 - bx1, by2 - by1);
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setArc(x, y, width, height, getAngleStart(), getAngleExtent(), type);
+    }
+
+    /**
+     * Sets the data that defines the arc.
+     * 
+     * @param point the upper left corner of the bounding rectangle.
+     * @param size the size of the bounding rectangle.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the angle witdth of the arc in degrees.
+     * @param type the closure type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArc(Point2D point, Dimension2D size, double start, double extent, int type) {
+        setArc(point.getX(), point.getY(), size.getWidth(), size.getHeight(), start, extent, type);
+    }
+
+    /**
+     * Sets the data that defines the arc.
+     * 
+     * @param rect the arc's bounding rectangle.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the angle witdth of the arc in degrees.
+     * @param type the closure type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArc(Rectangle2D rect, double start, double extent, int type) {
+        setArc(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), start, extent, type);
+    }
+
+    /**
+     * Sets the data that defines the arc by copying it from another Arc2D.
+     * 
+     * @param arc the arc whose data is copied into this arc.
+     */
+    public void setArc(Arc2D arc) {
+        setArc(arc.getX(), arc.getY(), arc.getWidth(), arc.getHeight(), arc
+                .getAngleStart(), arc.getAngleExtent(), arc.getArcType());
+    }
+
+    /**
+     * Sets the data for a circular arc by giving its center and radius.
+     * 
+     * @param x the x coordinate of the center of the circle.
+     * @param y the y coordinate of the center of the circle.
+     * @param radius the radius of the circle.
+     * @param start the start angle of the arc in degrees.
+     * @param extent the angle witdth of the arc in degrees.
+     * @param type the closure type, either {@link Arc2D#OPEN}, 
+     * {@link Arc2D#CHORD}, or {@link Arc2D#PIE}.
+     */
+    public void setArcByCenter(double x, double y, double radius, double start, double extent, int type) {
+        setArc(x - radius, y - radius, radius * 2.0, radius * 2.0, start, extent, type);
+    }
+
+    /**
+     * Sets the arc data for a circular arc based on two tangent lines
+     * and the radius. The two tangent lines are the lines from p1 
+     * to p2 and from p2 to p3, which determine a unique circle 
+     * with the given radius. The start and end points of the arc 
+     * are the points where the circle touches the two lines, and 
+     * the arc itself is the shorter of the two circle segments 
+     * determined by the two points (in other words, it is the 
+     * piece of the circle that is closer to the lines' intersection 
+     * point p2 and forms a concave shape with the segments from p1 to p2 
+     * and from p2 to p3).
+     * 
+     * @param p1 a point which determines one of the two tanget lines (with p2).
+     * @param p2 the point of intersection of the two tangent lines.
+     * @param p3 a point which determines one of the two tanget lines (with p2).
+     * @param radius the radius of the circular arc.
+     */
+    public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double radius) {
+        // Used simple geometric calculations of arc center, radius and angles by tangents
+        double a1 = -Math.atan2(p1.getY() - p2.getY(), p1.getX() - p2.getX());
+        double a2 = -Math.atan2(p3.getY() - p2.getY(), p3.getX() - p2.getX());
+        double am = (a1 + a2) / 2.0;
+        double ah = a1 - am;
+        double d = radius / Math.abs(Math.sin(ah));
+        double x = p2.getX() + d * Math.cos(am);
+        double y = p2.getY() - d * Math.sin(am);
+        ah = ah >= 0.0 ? Math.PI * 1.5 - ah : Math.PI * 0.5 - ah;
+        a1 = getNormAngle(Math.toDegrees(am - ah));
+        a2 = getNormAngle(Math.toDegrees(am + ah));
+        double delta = a2 - a1;
+        if (delta <= 0.0) {
+            delta += 360.0;
+        }
+        setArcByCenter(x, y, radius, a1, delta, type);
+    }
+
+    /**
+     * Sets a new start angle to be the angle given by the the vector 
+     * from the current center point to the specified point.
+     * 
+     * @param point the point that determines the new start angle.
+     */
+    public void setAngleStart(Point2D point) {
+        double angle = Math.atan2(point.getY() - getCenterY(), point.getX() - getCenterX());
+        setAngleStart(getNormAngle(-Math.toDegrees(angle)));
+    }
+
+    /**
+     * Sets the angles in terms of vectors from the current arc center 
+     * to the points (x1, y1) and (x2, y2). The start angle is given 
+     * by the vector from the current center to the point (x1, y1) and
+     * the end angle is given by the vector from the center to the point
+     * (x2, y2).
+     * 
+     * @param x1 the x coordinate of the point whose vector from the center
+     * point determines the new start angle of the arc.
+     * @param y1 the y coordinate of the point whose vector from the center
+     * point determines the new start angle of the arc.
+     * @param x2 the x coordinate of the point whose vector from the center
+     * point determines the new end angle of the arc.
+     * @param y2 the y coordinate of the point whose vector from the center
+     * point determines the new end angle of the arc.
+     */
+    public void setAngles(double x1, double y1, double x2, double y2) {
+        double cx = getCenterX();
+        double cy = getCenterY();
+        double a1 = getNormAngle(-Math.toDegrees(Math.atan2(y1 - cy, x1 - cx)));
+        double a2 = getNormAngle(-Math.toDegrees(Math.atan2(y2 - cy, x2 - cx)));
+        a2 -= a1;
+        if (a2 <= 0.0) {
+            a2 += 360.0;
+        }
+        setAngleStart(a1);
+        setAngleExtent(a2);
+    }
+
+    /**
+     * Sets the angles in terms of vectors from the current arc center 
+     * to the points p1 and p2. The start angle is given 
+     * by the vector from the current center to the point p1 and
+     * the end angle is given by the vector from the center to the point
+     * p2.
+     * 
+     * @param p1 the point whose vector from the center
+     * point determines the new start angle of the arc.
+     * @param p2 the point whose vector from the center
+     * point determines the new end angle of the arc.
+     */
+    public void setAngles(Point2D p1, Point2D p2) {
+        setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Normalizes the angle by removing extra winding (past 360 degrees)
+     * and placing it in the positive degree range.
+     * 
+     * @param angle - the source angle in degrees
+     * 
+     * @return an angle between 0 and 360 degrees which corresponds
+     * to the same direction vector as the source angle.
+     */
+    double getNormAngle(double angle) {
+        double n = Math.floor(angle / 360.0);
+        return angle - n * 360.0;
+    }
+
+    /**
+     * Determines whether the given angle is contained in the span of the arc.
+     * 
+     * @param angle the angle to test in degrees.
+     * 
+     * @return true, if the given angle is between the start angle and 
+     * the end angle of the arc.
+     */
+    public boolean containsAngle(double angle) {
+        double extent = getAngleExtent();
+        if (extent >= 360.0) {
+            return true;
+        }
+        angle = getNormAngle(angle);
+        double a1 = getNormAngle(getAngleStart());
+        double a2 = a1 + extent;
+        if (a2 > 360.0) {
+            return angle >= a1 || angle <= a2 - 360.0;
+        }
+        if (a2 < 0.0) {
+            return angle >= a2 + 360.0 || angle <= a1;
+        }
+        return extent > 0.0 ? a1 <= angle && angle <= a2 : a2 <= angle
+                && angle <= a1;
+    }
+
+    public boolean contains(double px, double py) {
+        // Normalize point
+        double nx = (px - getX()) / getWidth() - 0.5;
+        double ny = (py - getY()) / getHeight() - 0.5;
+
+        if ((nx * nx + ny * ny) > 0.25) {
+            return false;
+        }
+
+        double extent = getAngleExtent();
+        double absExtent = Math.abs(extent);
+        if (absExtent >= 360.0) {
+            return true;
+        }
+
+        boolean containsAngle = containsAngle(Math.toDegrees(-Math
+                .atan2(ny, nx)));
+        if (type == PIE) {
+            return containsAngle;
+        }
+        if (absExtent <= 180.0 && !containsAngle) {
+            return false;
+        }
+
+        Line2D l = new Line2D.Double(getStartPoint(), getEndPoint());
+        int ccw1 = l.relativeCCW(px, py);
+        int ccw2 = l.relativeCCW(getCenterX(), getCenterY());
+        return ccw1 == 0 || ccw2 == 0
+                || ((ccw1 + ccw2) == 0 ^ absExtent > 180.0);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+
+        if (!(contains(rx, ry) && contains(rx + rw, ry)
+                && contains(rx + rw, ry + rh) && contains(rx, ry + rh))) {
+            return false;
+        }
+
+        double absExtent = Math.abs(getAngleExtent());
+        if (type != PIE || absExtent <= 180.0 || absExtent >= 360.0) {
+            return true;
+        }
+
+        Rectangle2D r = new Rectangle2D.Double(rx, ry, rw, rh);
+
+        double cx = getCenterX();
+        double cy = getCenterY();
+        if (r.contains(cx, cy)) {
+            return false;
+        }
+
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+
+        return !r.intersectsLine(cx, cy, p1.getX(), p1.getY())
+                && !r.intersectsLine(cx, cy, p2.getX(), p2.getY());
+    }
+
+    @Override
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        // Check: Does arc contain rectangle's points
+        if (contains(rx, ry) || contains(rx + rw, ry) || contains(rx, ry + rh)
+                || contains(rx + rw, ry + rh)) {
+            return true;
+        }
+
+        double cx = getCenterX();
+        double cy = getCenterY();
+        Point2D p1 = getStartPoint();
+        Point2D p2 = getEndPoint();
+        Rectangle2D r = new Rectangle2D.Double(rx, ry, rw, rh);
+
+        // Check: Does rectangle contain arc's points
+        if (r.contains(p1) || r.contains(p2) || (type == PIE && r.contains(cx, cy))) {
+            return true;
+        }
+
+        if (type == PIE) {
+            if (r.intersectsLine(p1.getX(), p1.getY(), cx, cy) ||
+                r.intersectsLine(p2.getX(), p2.getY(), cx, cy))
+            {
+                return true;
+            }
+        } else {
+            if (r.intersectsLine(p1.getX(), p1.getY(), p2.getX(), p2.getY())) {
+                return true;
+            }
+        }
+
+        // Nearest rectangle point
+        double nx = cx < rx ? rx : (cx > rx + rw ? rx + rw : cx);
+        double ny = cy < ry ? ry : (cy > ry + rh ? ry + rh : cy);
+        return contains(nx, ny);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Area.java b/awt/java/awt/geom/Area.java
new file mode 100644
index 0000000..bc27d4e
--- /dev/null
+++ b/awt/java/awt/geom/Area.java
@@ -0,0 +1,317 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Area provides a minimal implementation for a generic shape.
+ */
+public class Area implements Shape, Cloneable {
+
+    /** The source Shape object. */
+    Shape s;
+
+    /**
+     * The Class NullIterator.
+     */
+    private static class NullIterator implements PathIterator {
+
+        /**
+         * Instantiates a new null iterator.
+         */
+        NullIterator() {
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return true;
+        }
+
+        public void next() {
+            // nothing
+        }
+
+        public int currentSegment(double[] coords) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+
+        public int currentSegment(float[] coords) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+
+    }
+
+    /**
+     * Instantiates a new area with no data.
+     */
+    public Area() {
+    }
+
+    /**
+     * Instantiates a new area with data given by the specified shape.
+     * 
+     * @param s the shape that gives the data for this Area
+     */
+    public Area(Shape s) {
+        if (s == null) {
+            throw new NullPointerException();
+        }
+        this.s = s;
+    }
+
+    public boolean contains(double x, double y) {
+        return s == null ? false : s.contains(x, y);
+    }
+
+    public boolean contains(double x, double y, double width, double height) {
+        return s == null ? false : s.contains(x, y, width, height);
+    }
+
+    public boolean contains(Point2D p) {
+        if (p == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.contains(p);
+    }
+
+    public boolean contains(Rectangle2D r) {
+        if (r == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.contains(r);
+    }
+
+    /**
+     * Tests whether the object is equal to this Area.
+     * 
+     * @param obj the object to compare
+     * 
+     * @return true, if successful
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean equals(Area obj) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    public boolean intersects(double x, double y, double width, double height) {
+        return s == null ? false : s.intersects(x, y, width, height);
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        if (r == null) {
+            throw new NullPointerException();
+        }
+        return s == null ? false : s.intersects(r);
+    }
+
+    public Rectangle getBounds() {
+        return s == null ? new Rectangle() : s.getBounds();
+    }
+
+    public Rectangle2D getBounds2D() {
+        return s == null ? new Rectangle2D.Double(): s.getBounds2D();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return s == null ? new NullIterator() : s.getPathIterator(t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return s == null ? new NullIterator() : s.getPathIterator(t, flatness);
+    }
+
+    /**
+     * Adds the specified area to this area.
+     * 
+     * @param area the area to add to this area
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void add(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Performs an exclusive or operation between this shape and the
+     * specified shape.
+     * 
+     * @param area the area to XOR against this area
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void exclusiveOr(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Extracts a Rectangle2D from the source shape if the underlying shape
+     * data describes a rectangle.
+     * 
+     * @return a Rectangle2D object if the source shape is rectangle, 
+     * or null if shape is empty or not rectangle.
+     */
+    Rectangle2D extractRectangle() {
+        if (s == null) {
+            return null;
+        }
+        float[] points = new float[12];
+        int count = 0;
+        PathIterator p = s.getPathIterator(null);
+        float[] coords = new float[6];
+        while(!p.isDone()) {
+            int type = p.currentSegment(coords);
+            if (count > 12 || type == PathIterator.SEG_QUADTO || type == PathIterator.SEG_CUBICTO) {
+                return null;
+            }
+            points[count++] = coords[0];
+            points[count++] = coords[1];
+            p.next();
+        }
+        if (points[0] == points[6] && points[6] == points[8] && points[2] == points[4] &&
+            points[1] == points[3] && points[3] == points[9] && points[5] == points[7])
+        {
+            return new Rectangle2D.Float(points[0], points[1], points[2] - points[0], points[7] - points[1]);
+        }
+        return null;
+    }
+    
+    /**
+     * Reduces the size of this Area by intersecting it with the 
+     * specified Area if they are both rectangles.
+     * 
+     * @see java.awt.geom.Rectangle2D#intersect(Rectangle2D, Rectangle2D, Rectangle2D)
+     * 
+     * @param area the area
+     */
+    public void intersect(Area area) {
+        Rectangle2D src1 = extractRectangle();
+        Rectangle2D src2 = area.extractRectangle();
+        if (src1 != null && src2 != null) {
+            Rectangle2D.intersect(src1, src2, (Rectangle2D)s);
+        }
+    }
+
+    /**
+     * Subtract the specified area from this area.
+     * 
+     * @param area the area to subtract
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void subtract(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is empty.
+     * 
+     * @return true, if this Area is empty
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isEmpty() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is polygonal.
+     * 
+     * @return true, if this Area is polygonal
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isPolygonal() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is rectangular.
+     * 
+     * @return true, if this Area is rectangular
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isRectangular() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if this Area is singular.
+     * 
+     * @return true, if this Area is singular
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public boolean isSingular() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Resets the data of this Area.
+     * 
+     * @throws NotImplementedException if this method is not implemented
+     */
+    public void reset() throws org.apache.harmony.luni.util.NotImplementedException {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Transforms the data of this Area according to the specified 
+     * AffineTransform.
+     * 
+     * @param t the transform to use to transform the data
+     */
+    public void transform(AffineTransform t) {
+        s = t.createTransformedShape(s);
+    }
+
+    /**
+     * Creates a new Area that is the result of transforming the data 
+     * of this Area according to the specified AffineTransform.
+     * 
+     * @param t the transform to use to transform the data
+     * 
+     * @return the new Area that is the result of transforming the data 
+     * of this Area according to the specified AffineTransform.
+     */
+    public Area createTransformedArea(AffineTransform t) {
+        return s == null ? new Area() : new Area(t.createTransformedShape(s));
+    }
+
+    @Override
+    public Object clone() {
+        return new Area(this);
+    }
+
+}
diff --git a/awt/java/awt/geom/CubicCurve2D.java b/awt/java/awt/geom/CubicCurve2D.java
new file mode 100644
index 0000000..3e440c8
--- /dev/null
+++ b/awt/java/awt/geom/CubicCurve2D.java
@@ -0,0 +1,945 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class CubicCurve2D is a Shape that represents a segment of a 
+ * quadratic (Bezier) curve. The curved segment is determined by four points:
+ * a start point, an end point, and two control points. 
+ * The control points give information about the tangent and next 
+ * derivative at the endpoints according to the standard theory of 
+ * Bezier curves. For more information on Bezier curves, 
+ * see <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">this article</a>.
+ */
+public abstract class CubicCurve2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of CubicCurve2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends CubicCurve2D {
+
+        /** The x coordinate of the starting point. */
+        public float x1;
+        
+        /** The y coordinate of the starting point. */
+        public float y1;
+        
+        /** The x coordinate of the first control point. */
+        public float ctrlx1;
+        
+        /** The y coordinate of the first control point. */
+        public float ctrly1;
+        
+        /** The x coordinate of the second control point. */
+        public float ctrlx2;
+        
+        /** The y coordinate of the second control point. */
+        public float ctrly2;
+        
+        /** The x coordinate of the end point. */
+        public float x2;
+        
+        /** The y coordinate of the end point. */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued CubicCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued CubicCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param ctrlx1 the x coordinate of the first control point
+         * @param ctrly1 the y coordinate of the first control point
+         * @param ctrlx2 the x coordinate of the second control point
+         * @param ctrly2 the y coordinate of the second control point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Float(float x1, float y1, float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x2, float y2) {
+            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX1() {
+            return ctrlx1;
+        }
+
+        @Override
+        public double getCtrlY1() {
+            return ctrly1;
+        }
+
+        @Override
+        public double getCtrlX2() {
+            return ctrlx2;
+        }
+
+        @Override
+        public double getCtrlY2() {
+            return ctrly2;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlP1() {
+            return new Point2D.Float(ctrlx1, ctrly1);
+        }
+
+        @Override
+        public Point2D getCtrlP2() {
+            return new Point2D.Float(ctrlx2, ctrly2);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
+                double ctrlx2, double ctrly2, double x2, double y2)
+        {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.ctrlx1 = (float)ctrlx1;
+            this.ctrly1 = (float)ctrly1;
+            this.ctrlx2 = (float)ctrlx2;
+            this.ctrly2 = (float)ctrly2;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values of the curve.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param ctrlx1 the x coordinate of the first control point
+         * @param ctrly1 the y coordinate of the first control point
+         * @param ctrlx2 the x coordinate of the second control point
+         * @param ctrly2 the y coordinate of the second control point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public void setCurve(float x1, float y1, float ctrlx1, float ctrly1,
+                float ctrlx2, float ctrly2, float x2, float y2)
+        {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx1 = ctrlx1;
+            this.ctrly1 = ctrly1;
+            this.ctrlx2 = ctrlx2;
+            this.ctrly2 = ctrly2;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx1 = Math.min(Math.min(x1, x2), Math.min(ctrlx1, ctrlx2));
+            float ry1 = Math.min(Math.min(y1, y2), Math.min(ctrly1, ctrly2));
+            float rx2 = Math.max(Math.max(x1, x2), Math.max(ctrlx1, ctrlx2));
+            float ry2 = Math.max(Math.max(y1, y2), Math.max(ctrly1, ctrly2));
+            return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of CubicCurve2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends CubicCurve2D {
+
+        /** The x coordinate of the starting point. */
+        public double x1;
+        
+        /** The y coordinate of the starting point. */
+        public double y1;
+        
+        /** The x coordinate of the first control point. */
+        public double ctrlx1;
+        
+        /** The y coordinate of the first control point. */
+        public double ctrly1;
+        
+        /** The x coordinate of the second control point. */
+        public double ctrlx2;
+        
+        /** The y coordinate of the second control point. */
+        public double ctrly2;
+        
+        /** The x coordinate of the end point. */
+        public double x2;
+        
+        /** The y coordinate of the end point. */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued CubicCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued CubicCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param ctrlx1 the x coordinate of the first control point
+         * @param ctrly1 the y coordinate of the first control point
+         * @param ctrlx2 the x coordinate of the second control point
+         * @param ctrly2 the y coordinate of the second control point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Double(double x1, double y1, double ctrlx1, double ctrly1,
+                double ctrlx2, double ctrly2, double x2, double y2) {
+            setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX1() {
+            return ctrlx1;
+        }
+
+        @Override
+        public double getCtrlY1() {
+            return ctrly1;
+        }
+
+        @Override
+        public double getCtrlX2() {
+            return ctrlx2;
+        }
+
+        @Override
+        public double getCtrlY2() {
+            return ctrly2;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlP1() {
+            return new Point2D.Double(ctrlx1, ctrly1);
+        }
+
+        @Override
+        public Point2D getCtrlP2() {
+            return new Point2D.Double(ctrlx2, ctrly2);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
+                double ctrlx2, double ctrly2, double x2, double y2)
+        {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx1 = ctrlx1;
+            this.ctrly1 = ctrly1;
+            this.ctrlx2 = ctrlx2;
+            this.ctrly2 = ctrly2;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx1 = Math.min(Math.min(x1, x2), Math.min(ctrlx1, ctrlx2));
+            double ry1 = Math.min(Math.min(y1, y2), Math.min(ctrly1, ctrly2));
+            double rx2 = Math.max(Math.max(x1, x2), Math.max(ctrlx1, ctrlx2));
+            double ry2 = Math.max(Math.max(y1, y2), Math.max(ctrly1, ctrly2));
+            return new Rectangle2D.Double(rx1, ry1, rx2 - rx1, ry2 - ry1);
+        }
+    }
+
+    /*
+     * CubicCurve2D path iterator 
+     */
+    /**
+     * The Iterator class for the Shape CubicCurve2D.
+     */
+    class Iterator implements PathIterator {
+
+        /** The source CubicCurve2D object. */
+        CubicCurve2D c;
+        
+        /** The path iterator transformation. */
+        AffineTransform t;
+        
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new CubicCurve2D.Iterator for given line and transformation
+         * 
+         * @param c - the source CubicCurve2D object
+         * @param t the t
+         */
+        Iterator(CubicCurve2D c, AffineTransform t) {
+            this.c = c;
+            this.t = t;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 1;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = c.getX1();
+                coords[1] = c.getY1();
+                count = 1;
+            } else {
+                type = SEG_CUBICTO;
+                coords[0] = c.getCtrlX1();
+                coords[1] = c.getCtrlY1();
+                coords[2] = c.getCtrlX2();
+                coords[3] = c.getCtrlY2();
+                coords[4] = c.getX2();
+                coords[5] = c.getY2();
+                count = 3;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)c.getX1();
+                coords[1] = (float)c.getY1();
+                count = 1;
+            } else {
+                type = SEG_CUBICTO;
+                coords[0] = (float)c.getCtrlX1();
+                coords[1] = (float)c.getCtrlY1();
+                coords[2] = (float)c.getCtrlX2();
+                coords[3] = (float)c.getCtrlY2();
+                coords[4] = (float)c.getX2();
+                coords[5] = (float)c.getY2();
+                count = 3;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new 2-D cubic curve.
+     */
+    protected CubicCurve2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the starting point.
+     * 
+     * @return the starting point
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the x coordinate of the first control point.
+     * 
+     * @return the x coordinate of the first control point
+     */
+    public abstract double getCtrlX1();
+
+    /**
+     * Gets the y coordinate of the first control point.
+     * 
+     * @return the y coordinate of the first control point
+     */
+    public abstract double getCtrlY1();
+
+    /**
+     * Gets the second control point.
+     * 
+     * @return the second control point
+     */
+    public abstract Point2D getCtrlP1();
+
+    /**
+     * Gets the x coordinate of the second control point.
+     * 
+     * @return the x coordinate of the second control point
+     */
+    public abstract double getCtrlX2();
+
+    /**
+     * Gets the y coordinate of the second control point.
+     * 
+     * @return the y coordinate of the second control point
+     */
+    public abstract double getCtrlY2();
+
+    /**
+     * Gets the second control point.
+     * 
+     * @return the second control point
+     */
+    public abstract Point2D getCtrlP2();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x coordinate of the end point
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the end point.
+     * 
+     * @return the end point
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param ctrlx1 the x coordinate of the first control point
+     * @param ctrly1 the y coordinate of the first control point
+     * @param ctrlx2 the x coordinate of the second control point
+     * @param ctrly2 the y coordinate of the second control point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     */
+    public abstract void setCurve(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2);
+
+    /**
+     * Sets the data of the curve as point objects.
+     * 
+     * @param p1 the starting point
+     * @param cp1 the first control point
+     * @param cp2 the second control point
+     * @param p2 the end point
+     * 
+     * @throws NullPointerException if any of the points is null.
+     */
+    public void setCurve(Point2D p1, Point2D cp1, Point2D cp2, Point2D p2) {
+        setCurve(
+                p1.getX(), p1.getY(),
+                cp1.getX(), cp1.getY(),
+                cp2.getX(), cp2.getY(),
+                p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of values. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#setCurve(double, double, double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of values containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 8.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public void setCurve(double[] coords, int offset) {
+        setCurve(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 6], coords[offset + 7]);
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of points. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#setCurve(Point2D, Point2D, Point2D, Point2D)}
+     * 
+     * @param points the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + .
+     * @throws NullPointerException if the point array is null.
+     */
+    public void setCurve(Point2D[] points, int offset) {
+        setCurve(
+                points[offset + 0].getX(), points[offset + 0].getY(),
+                points[offset + 1].getX(), points[offset + 1].getY(),
+                points[offset + 2].getX(), points[offset + 2].getY(),
+                points[offset + 3].getX(), points[offset + 3].getY());
+    }
+
+    /**
+     * Sets the data of the curve by copying it from another CubicCurve2D.
+     * 
+     * @param curve the curve to copy the data points from
+     * 
+     * @throws NullPointerException if the curve is null.
+     */
+    public void setCurve(CubicCurve2D curve) {
+        setCurve(
+                curve.getX1(), curve.getY1(),
+                curve.getCtrlX1(), curve.getCtrlY1(),
+                curve.getCtrlX2(), curve.getCtrlY2(),
+                curve.getX2(), curve.getY2());
+    }
+
+    /**
+     * Gets the square of the flatness of this curve, where the flatness is the 
+     * maximum distance from the curves control points to the 
+     * line segment connecting the two points.
+     * 
+     * @return the square of the flatness
+     */
+    public double getFlatnessSq() {
+        return getFlatnessSq(
+                getX1(), getY1(),
+                getCtrlX1(), getCtrlY1(),
+                getCtrlX2(), getCtrlY2(),
+                getX2(), getY2());
+    }
+
+    /**
+     * Gets the square of the flatness of the cubic curve segment 
+     * defined by the specified values.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param ctrlx1 the x coordinate of the first control point
+     * @param ctrly1 the y coordinate of the first control point
+     * @param ctrlx2 the x coordinate of the second control point
+     * @param ctrly2 the y coordinate of the second control point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     * 
+     * @return the square of the flatness
+     */
+    public static double getFlatnessSq(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2)
+    {
+        return Math.max(
+                Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx1, ctrly1),
+                Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx2, ctrly2));
+    }
+
+    /**
+     * Gets the square of the flatness of the cubic curve segment 
+     * defined by the specified values. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#getFlatnessSq(double, double, double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the square of the flatness
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + .
+     * @throws NullPointerException if the point array is null.
+     */
+    public static double getFlatnessSq(double coords[], int offset) {
+        return getFlatnessSq(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 6], coords[offset + 7]);
+    }
+
+    /**
+     * Gets the flatness of this curve, where the flatness is the 
+     * maximum distance from the curves control points to the 
+     * line segment connecting the two points.
+     * 
+     * @return the flatness of this curve
+     */
+    public double getFlatness() {
+        return getFlatness(
+                getX1(), getY1(),
+                getCtrlX1(), getCtrlY1(),
+                getCtrlX2(), getCtrlY2(),
+                getX2(), getY2());
+    }
+
+    /**
+     * Gets the flatness of the cubic curve segment 
+     * defined by the specified values.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param ctrlx1 the x coordinate of the first control point
+     * @param ctrly1 the y coordinate of the first control point
+     * @param ctrlx2 the x coordinate of the second control point
+     * @param ctrly2 the y coordinate of the second control point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     * 
+     * @return the flatness
+     */
+    public static double getFlatness(double x1, double y1, double ctrlx1, double ctrly1,
+            double ctrlx2, double ctrly2, double x2, double y2)
+    {
+        return Math.sqrt(getFlatnessSq(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2));
+    }
+
+    /**
+     * Gets the flatness of the cubic curve segment 
+     * defined by the specified values. The values are read in the same order as the arguments
+     * of the method {@link CubicCurve2D#getFlatness(double, double, double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the flatness
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + .
+     * @throws NullPointerException if the point array is null.
+     */
+    public static double getFlatness(double coords[], int offset) {
+        return getFlatness(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 6], coords[offset + 7]);
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing this
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the average of curve's two control points. 
+     * The two new control points (nearest the new endpoint) are computed
+     * by averaging the original control points with the new endpoint.
+     * The data of this curve is left unchanged.
+     * 
+     * @param left the CubicCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the CubicCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if either curve is null.
+     */
+    public void subdivide(CubicCurve2D left, CubicCurve2D right) {
+        subdivide(this, left, right);
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing the specified
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the average of curve's two control points. 
+     * The two new control points (nearest the new endpoint) are computed
+     * by averaging the original control points with the new endpoint.
+     * The data of the source curve is left unchanged.
+     * 
+     * @param src the original curve to be divided in two
+     * @param left the CubicCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the CubicCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if either curve is null.
+     */
+    public static void subdivide(CubicCurve2D src, CubicCurve2D left, CubicCurve2D right) {
+        double x1 = src.getX1();
+        double y1 = src.getY1();
+        double cx1 = src.getCtrlX1();
+        double cy1 = src.getCtrlY1();
+        double cx2 = src.getCtrlX2();
+        double cy2 = src.getCtrlY2();
+        double x2 = src.getX2();
+        double y2 = src.getY2();
+        double cx = (cx1 + cx2) / 2.0;
+        double cy = (cy1 + cy2) / 2.0;
+        cx1 = (x1 + cx1) / 2.0;
+        cy1 = (y1 + cy1) / 2.0;
+        cx2 = (x2 + cx2) / 2.0;
+        cy2 = (y2 + cy2) / 2.0;
+        double ax = (cx1 + cx) / 2.0;
+        double ay = (cy1 + cy) / 2.0;
+        double bx = (cx2 + cx) / 2.0;
+        double by = (cy2 + cy) / 2.0;
+        cx = (ax + bx) / 2.0;
+        cy = (ay + by) / 2.0;
+        if (left != null) {
+            left.setCurve(x1, y1, cx1, cy1, ax, ay, cx, cy);
+        }
+        if (right != null) {
+            right.setCurve(cx, cy, bx, by, cx2, cy2, x2, y2);
+        }
+    }
+
+    /**
+     * Creates the data for two cubic curves by dividing the specified
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the average of curve's two control points. 
+     * The two new control points (nearest the new endpoint) are computed
+     * by averaging the original control points with the new endpoint.
+     * The data of the source curve is left unchanged. The data for the 
+     * three curves is read/written in the usual order: { x1, y1, 
+     * ctrlx1, ctrly1, ctrlx2, crtry2, x2, y3 }
+     * 
+     * @param src the array that gives the data values for the source curve
+     * @param srcOff the offset in the src array to read the values from
+     * @param left the array where the coordinates of the start curve should be written
+     * @param leftOff the offset in the left array to start writing the values
+     * @param right the array where the coordinates of the end curve should be written
+     * @param rightOff the offset in the right array to start writing the values
+     * 
+     * @throws ArrayIndexOutOfBoundsException if src.length < srcoff + 8
+     * or if left.length < leftOff + 8 or if right.length < rightOff + 8.
+     * @throws NullPointerException if one of the arrays is null.
+     */
+    public static void subdivide(double src[], int srcOff, double left[], int leftOff, double right[], int rightOff) {
+        double x1 = src[srcOff + 0];
+        double y1 = src[srcOff + 1];
+        double cx1 = src[srcOff + 2];
+        double cy1 = src[srcOff + 3];
+        double cx2 = src[srcOff + 4];
+        double cy2 = src[srcOff + 5];
+        double x2 = src[srcOff + 6];
+        double y2 = src[srcOff + 7];
+        double cx = (cx1 + cx2) / 2.0;
+        double cy = (cy1 + cy2) / 2.0;
+        cx1 = (x1 + cx1) / 2.0;
+        cy1 = (y1 + cy1) / 2.0;
+        cx2 = (x2 + cx2) / 2.0;
+        cy2 = (y2 + cy2) / 2.0;
+        double ax = (cx1 + cx) / 2.0;
+        double ay = (cy1 + cy) / 2.0;
+        double bx = (cx2 + cx) / 2.0;
+        double by = (cy2 + cy) / 2.0;
+        cx = (ax + bx) / 2.0;
+        cy = (ay + by) / 2.0;
+        if (left != null) {
+            left[leftOff + 0] = x1;
+            left[leftOff + 1] = y1;
+            left[leftOff + 2] = cx1;
+            left[leftOff + 3] = cy1;
+            left[leftOff + 4] = ax;
+            left[leftOff + 5] = ay;
+            left[leftOff + 6] = cx;
+            left[leftOff + 7] = cy;
+        }
+        if (right != null) {
+            right[rightOff + 0] = cx;
+            right[rightOff + 1] = cy;
+            right[rightOff + 2] = bx;
+            right[rightOff + 3] = by;
+            right[rightOff + 4] = cx2;
+            right[rightOff + 5] = cy2;
+            right[rightOff + 6] = x2;
+            right[rightOff + 7] = y2;
+        }
+    }
+
+    /**
+     * Finds the roots of the cubic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[3]*x*x*x + eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written back into the array eqn starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been changed by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * cubic polynomial to solve.
+     * 
+     * @return the number of roots of the cubic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 4.
+     * @throws NullPointerException if the array is null.
+     */
+    public static int solveCubic(double eqn[]) {
+        return solveCubic(eqn, eqn);
+    }
+
+    /**
+     * Finds the roots of the cubic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[3]*x*x*x + eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written into the array res starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been changed by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * cubic polynomial to solve.
+     * @param res the array that this method writes the results into
+     * 
+     * @return the number of roots of the cubic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 4 or 
+     * if res.length is less than the number of roots.
+     * @throws NullPointerException if either array is null.
+     */
+    public static int solveCubic(double eqn[], double res[]) {
+        return Crossing.solveCubic(eqn, res);
+    }
+
+    public boolean contains(double px, double py) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(at), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+}
\ No newline at end of file
diff --git a/awt/java/awt/geom/Dimension2D.java b/awt/java/awt/geom/Dimension2D.java
new file mode 100644
index 0000000..eef63e6
--- /dev/null
+++ b/awt/java/awt/geom/Dimension2D.java
@@ -0,0 +1,78 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Class Dimension2D represents a size (width and height) of a 
+ * geometric object. It stores double-valued data in order to be compatible
+ * with high-precision geometric operations.
+ */
+public abstract class Dimension2D implements Cloneable {
+
+    /**
+     * Instantiates a new dimension 2d with no data.
+     */
+    protected Dimension2D() {
+    }
+
+    /**
+     * Gets the width.
+     * 
+     * @return the width
+     */
+    public abstract double getWidth();
+
+    /**
+     * Gets the height.
+     * 
+     * @return the height
+     */
+    public abstract double getHeight();
+
+    /**
+     * Sets the width and height.
+     * 
+     * @param width the width
+     * @param height the height
+     */
+    public abstract void setSize(double width, double height);
+
+    /**
+     * Sets the width and height based on the data of another 
+     * Dimension2D object.
+     * 
+     * @param d the Dimension2D object providing the data to copy 
+     * into this Dimension2D object
+     */
+    public void setSize(Dimension2D d) {
+        setSize(d.getWidth(), d.getHeight());
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+}
+
diff --git a/awt/java/awt/geom/Ellipse2D.java b/awt/java/awt/geom/Ellipse2D.java
new file mode 100644
index 0000000..33464af
--- /dev/null
+++ b/awt/java/awt/geom/Ellipse2D.java
@@ -0,0 +1,403 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Ellipse2D describes an ellipse defined by a rectangular
+ * area in which it is inscribed.
+ */
+public abstract class Ellipse2D extends RectangularShape {
+
+    /**
+     * The Class Float is the subclass of Ellipse2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends Ellipse2D {
+
+        /** The x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public float x;
+        
+        /** The y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public float y;
+        
+        /** The width of the ellipse's bounding rectangle. */
+        public float width;
+        
+        /** The height of the ellipse's bounding rectangle. */
+        public float height;
+
+        /**
+         * Instantiates a new float-valued Ellipse2D.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Ellipse2D with the specified data.
+         * 
+         * @param x the x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param y the y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param width the width of the ellipse's bounding rectangle
+         * @param height the height of the ellipse's bounding rectangle
+         */
+        public Float(float x, float y, float width, float height) {
+            setFrame(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        /**
+         * Sets the data of the ellipse's bounding rectangle.
+         * 
+         * @param x the x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param y the y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param width the width of the ellipse's bounding rectangle
+         * @param height the height of the ellipse's bounding rectangle
+         */
+        public void setFrame(float x, float y, float width, float height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setFrame(double x, double y, double width, double height) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Float(x, y, width, height);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Ellipse2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends Ellipse2D {
+
+        /** The x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public double x;
+        
+        /** The y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle. */
+        public double y;
+        
+        /** The width of the ellipse's bounding rectangle. */
+        public double width;
+        
+        /** The height of the ellipse's bounding rectangle. */
+        public double height;
+
+        /**
+         * Instantiates a new double-valued Ellipse2D.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Ellipse2D with the specified
+         * data.
+         * 
+         * @param x the x coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param y the y coordinate of the upper left corner of the ellipse's
+         * bounding rectangle
+         * @param width the width of the ellipse's bounding rectangle
+         * @param height the height of the ellipse's bounding rectangle
+         */
+        public Double(double x, double y, double width, double height) {
+            setFrame(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setFrame(double x, double y, double width, double height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+    }
+
+    /*
+     * Ellipse2D path iterator 
+     */
+    /**
+     * The subclass of PathIterator to traverse an Ellipse2D.
+     */
+    class Iterator implements PathIterator {
+
+        /*
+         * Ellipse is subdivided into four quarters by x and y axis. Each part approximated by
+         * cubic Bezier curve. Arc in first quarter is started in (a, 0) and finished in (0, b) points.
+         * Control points for cubic curve wiil be (a, 0), (a, m), (n, b) and (0, b) where n and m are
+         * calculated based on requirement Bezier curve in point 0.5 should lay on the arc.
+         */
+
+        /** The coefficient to calculate control points of Bezier curves. */
+        final double u = 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+
+        /** The points coordinates calculation table. */
+        final double points[][] = {
+                { 1.0, 0.5 + u, 0.5 + u, 1.0, 0.5, 1.0 },
+                { 0.5 - u, 1.0, 0.0, 0.5 + u, 0.0, 0.5 },
+                { 0.0, 0.5 - u, 0.5 - u, 0.0, 0.5, 0.0 },
+                { 0.5 + u, 0.0, 1.0, 0.5 - u, 1.0, 0.5 }
+        };
+
+        /** The x coordinate of left-upper corner of the ellipse bounds. */
+        double x;
+        
+        /** The y coordinate of left-upper corner of the ellipse bounds. */
+        double y;
+        
+        /** The width of the ellipse bounds. */
+        double width;
+        
+        /** The height of the ellipse bounds. */
+        double height;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new Ellipse2D.Iterator for given ellipse and transformation
+         * 
+         * @param e - the source Ellipse2D object
+         * @param t the t
+         */
+        Iterator(Ellipse2D e, AffineTransform t) {
+            this.x = e.getX();
+            this.y = e.getY();
+            this.width = e.getWidth();
+            this.height = e.getHeight();
+            this.t = t;
+            if (width < 0.0 || height < 0.0) {
+                index = 6;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 5;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                double p[] = points[3];
+                coords[0] = x + p[4] * width;
+                coords[1] = y + p[5] * height;
+            } else {
+                type = SEG_CUBICTO;
+                count = 3;
+                double p[] = points[index - 1];
+                int j = 0;
+                for (int i = 0; i < 3; i++) {
+                    coords[j] = x + p[j++] * width;
+                    coords[j] = y + p[j++] * height;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                count = 1;
+                double p[] = points[3];
+                coords[0] = (float)(x + p[4] * width);
+                coords[1] = (float)(y + p[5] * height);
+            } else {
+                type = SEG_CUBICTO;
+                count = 3;
+                int j = 0;
+                double p[] = points[index - 1];
+                for (int i = 0; i < 3; i++) {
+                    coords[j] = (float)(x + p[j++] * width);
+                    coords[j] = (float)(y + p[j++] * height);
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new Ellipse2D.
+     */
+    protected Ellipse2D() {
+    }
+
+    public boolean contains(double px, double py) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double a = (px - getX()) / getWidth() - 0.5;
+        double b = (py - getY()) / getHeight() - 0.5;
+
+        return a * a + b * b < 0.25;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double cx = getX() + getWidth() / 2.0;
+        double cy = getY() + getHeight() / 2.0;
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
+        double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
+
+        return contains(nx, ny);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        return
+            contains(rx1, ry1) &&
+            contains(rx2, ry1) &&
+            contains(rx2, ry2) &&
+            contains(rx1, ry2);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+}
+
diff --git a/awt/java/awt/geom/FlatteningPathIterator.java b/awt/java/awt/geom/FlatteningPathIterator.java
new file mode 100644
index 0000000..ca5c7c2
--- /dev/null
+++ b/awt/java/awt/geom/FlatteningPathIterator.java
@@ -0,0 +1,326 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class FlatteningPathIterator takes a PathIterator for traversing 
+ * a curved shape and flattens it by estimating the curve as a series 
+ * of line segments. The flattening factor indicates how far the 
+ * estimating line segments are allowed to be from the actual curve:
+ * the FlatteningPathIterator will keep dividing each curved segment 
+ * into smaller and smaller flat segments until either the segments 
+ * are withing the flattening factor of the curve or until the buffer
+ * limit is reached.
+ */
+public class FlatteningPathIterator implements PathIterator {
+
+    /** The default points buffer size. */
+    private static final int BUFFER_SIZE = 16;
+    
+    /** The default curve subdivision limit. */
+    private static final int BUFFER_LIMIT = 16;
+
+    /** The points buffer capacity. */
+    private static final int BUFFER_CAPACITY = 16;
+    
+    /** The type of current segment to be flat. */
+    int bufType;
+    
+    /** The curve subdivision limit. */
+    int bufLimit;
+    
+    /** The current points buffer size. */
+    int bufSize;
+    
+    /** The inner cursor position in points buffer. */
+    int bufIndex;
+    
+    /** The current subdivision count. */
+    int bufSubdiv;
+
+    /** The points buffer. */
+    double buf[];
+    
+    /** The indicator of empty points buffer. */
+    boolean bufEmpty = true;
+    
+    /** The source PathIterator. */
+    PathIterator p;
+    
+    /** The flatness of new path. */
+    double flatness;
+    
+    /** The square of flatness. */
+    double flatness2;
+    
+    /** The x coordinate of previous path segment. */
+    double px;
+
+    /** The y coordinate of previous path segment. */
+    double py;
+    
+    /** The tamporary buffer for getting points from PathIterator. */
+    double coords[] = new double[6];
+
+    /**
+     * Instantiates a new flattening path iterator given the path 
+     * iterator for a (possibly) curved path and a flattening factor
+     * which indicates how close together the points on the curve 
+     * should be chosen. The buffer limit defaults to 16 which means 
+     * that each curve will be divided into no more than 16 segments 
+     * regardless of the flattening factor.
+     * 
+     * @param path the path iterator of the original curve
+     * @param flatness the flattening factor that indicates how far the 
+     * flat path is allowed to be from the actual curve in order to 
+     * decide when to stop dividing the path into smaller and smaller
+     * segments.
+     * 
+     * @throws IllegalArgumentException if the flatness is less than zero.
+     * @throws NullPointerException if the path is null.
+     */
+    public FlatteningPathIterator(PathIterator path, double flatness) {
+        this(path, flatness, BUFFER_LIMIT);
+    }
+
+    /**
+     * Instantiates a new flattening path iterator given the path 
+     * iterator for a (possibly) curved path and a flattening factor
+     * and a buffer limit. The FlatteningPathIterator will keep 
+     * dividing each curved segment into smaller and smaller flat segments 
+     * until either the segments are withing the flattening factor of the 
+     * curve or until the buffer limit is reached.
+     * 
+     * @param path the path iterator of the original curve
+     * @param flatness the flattening factor that indicates how far the 
+     * flat path is allowed to be from the actual curve in order to 
+     * decide when to stop dividing the path into smaller and smaller
+     * segments.
+     * @param limit the maximum number of flat segments to divide each 
+     * curve into
+     * 
+     * @throws IllegalArgumentException if the flatness or limit is less than zero.
+     * @throws NullPointerException if the path is null.
+     */
+    public FlatteningPathIterator(PathIterator path, double flatness, int limit) {
+        if (flatness < 0.0) {
+            // awt.206=Flatness is less then zero
+            throw new IllegalArgumentException(Messages.getString("awt.206")); //$NON-NLS-1$
+        }
+        if (limit < 0) {
+            // awt.207=Limit is less then zero
+            throw new IllegalArgumentException(Messages.getString("awt.207")); //$NON-NLS-1$
+        }
+        if (path == null) {
+            // awt.208=Path is null
+            throw new NullPointerException(Messages.getString("awt.208")); //$NON-NLS-1$
+        }
+        this.p = path;
+        this.flatness = flatness;
+        this.flatness2 = flatness * flatness;
+        this.bufLimit = limit;
+        this.bufSize = Math.min(bufLimit, BUFFER_SIZE);
+        this.buf = new double[bufSize];
+        this.bufIndex = bufSize;
+    }
+
+    /**
+     * Gets the flattening factor.
+     * 
+     * @return the flattening factor
+     */
+    public double getFlatness() {
+        return flatness;
+    }
+
+    /**
+     * Gets the maximum number of subdivisions per curved segment.
+     * 
+     * @return the maximum number of subdivisions per curved segment
+     */
+    public int getRecursionLimit() {
+        return bufLimit;
+    }
+
+    public int getWindingRule() {
+        return p.getWindingRule();
+    }
+
+    public boolean isDone() {
+        return bufEmpty && p.isDone();
+    }
+
+    /**
+     * Calculates flat path points for current segment of the source shape.
+     * 
+     * Line segment is flat by itself. Flatness of quad and cubic curves evaluated by getFlatnessSq() method.
+     * Curves subdivided until current flatness is bigger than user defined and subdivision limit isn't exhausted.
+     * Single source segment translated to series of buffer points. The less flatness the bigger serries.
+     * Every currentSegment() call extract one point from the buffer. When series completed evaluate() takes next source shape segment.
+     */
+    void evaluate() {
+        if (bufEmpty) {
+            bufType = p.currentSegment(coords);
+        }
+
+        switch (bufType) {
+        case SEG_MOVETO:
+        case SEG_LINETO:
+            px = coords[0];
+            py = coords[1];
+            break;
+        case SEG_QUADTO:
+            if (bufEmpty) {
+                bufIndex -= 6;
+                buf[bufIndex + 0] = px;
+                buf[bufIndex + 1] = py;
+                System.arraycopy(coords, 0, buf, bufIndex + 2, 4);
+                bufSubdiv = 0;
+            }
+
+            while (bufSubdiv < bufLimit) {
+                if (QuadCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
+                    break;
+                }
+
+                // Realloc buffer
+                if (bufIndex <= 4) {
+                    double tmp[] = new double[bufSize + BUFFER_CAPACITY];
+                    System.arraycopy(
+                            buf, bufIndex,
+                            tmp, bufIndex + BUFFER_CAPACITY,
+                            bufSize - bufIndex);
+                    buf = tmp;
+                    bufSize += BUFFER_CAPACITY;
+                    bufIndex += BUFFER_CAPACITY;
+                }
+
+                QuadCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 4, buf, bufIndex);
+
+                bufIndex -= 4;
+                bufSubdiv++;
+            }
+
+            bufIndex += 4;
+            px = buf[bufIndex];
+            py = buf[bufIndex + 1];
+
+            bufEmpty = (bufIndex == bufSize - 2);
+            if (bufEmpty) {
+                bufIndex = bufSize;
+                bufType = SEG_LINETO;
+            } else {
+                bufSubdiv--;
+            }
+            break;
+        case SEG_CUBICTO:
+            if (bufEmpty) {
+                bufIndex -= 8;
+                buf[bufIndex + 0] = px;
+                buf[bufIndex + 1] = py;
+                System.arraycopy(coords, 0, buf, bufIndex + 2, 6);
+                bufSubdiv = 0;
+            }
+
+            while (bufSubdiv < bufLimit) {
+                if (CubicCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
+                    break;
+                }
+
+                // Realloc buffer
+                if (bufIndex <= 6) {
+                    double tmp[] = new double[bufSize + BUFFER_CAPACITY];
+                    System.arraycopy(
+                            buf, bufIndex,
+                            tmp, bufIndex + BUFFER_CAPACITY,
+                            bufSize - bufIndex);
+                    buf = tmp;
+                    bufSize += BUFFER_CAPACITY;
+                    bufIndex += BUFFER_CAPACITY;
+                }
+
+                CubicCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 6, buf, bufIndex);
+
+                bufIndex -= 6;
+                bufSubdiv++;
+            }
+
+            bufIndex += 6;
+            px = buf[bufIndex];
+            py = buf[bufIndex + 1];
+
+            bufEmpty = (bufIndex == bufSize - 2);
+            if (bufEmpty) {
+                bufIndex = bufSize;
+                bufType = SEG_LINETO;
+            } else {
+                bufSubdiv--;
+            }
+            break;
+        }
+
+    }
+
+    public void next() {
+        if (bufEmpty) {
+            p.next();
+        }
+    }
+
+    public int currentSegment(float[] coords) {
+        if (isDone()) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4Bx")); //$NON-NLS-1$
+        }
+        evaluate();
+        int type = bufType;
+        if (type != SEG_CLOSE) {
+            coords[0] = (float)px;
+            coords[1] = (float)py;
+            if (type != SEG_MOVETO) {
+                type = SEG_LINETO;
+            }
+        }
+        return type;
+    }
+
+    public int currentSegment(double[] coords) {
+        if (isDone()) {
+            // awt.4B=Iterator out of bounds
+            throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+        }
+        evaluate();
+        int type = bufType;
+        if (type != SEG_CLOSE) {
+            coords[0] = px;
+            coords[1] = py;
+            if (type != SEG_MOVETO) {
+                type = SEG_LINETO;
+            }
+        }
+        return type;
+    }
+}
+
diff --git a/awt/java/awt/geom/GeneralPath.java b/awt/java/awt/geom/GeneralPath.java
new file mode 100644
index 0000000..36b01c4
--- /dev/null
+++ b/awt/java/awt/geom/GeneralPath.java
@@ -0,0 +1,566 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class GeneralPath represents a shape whose outline is given 
+ * by different types of curved and straight segments.
+ */
+public final class GeneralPath implements Shape, Cloneable {
+
+    /** The Constant WIND_EVEN_ODD see {@link PathIterator#WIND_EVEN_ODD}. */
+    public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;
+    
+    /** The Constant WIND_NON_ZERO see {@link PathIterator#WIND_NON_ZERO}. */
+    public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
+
+    /** The buffers size. */
+    private static final int BUFFER_SIZE = 10;
+    
+    /** The buffers capacity. */
+    private static final int BUFFER_CAPACITY = 10;
+
+    /** The point's types buffer. */
+    byte[] types;
+    
+    /** The points buffer. */
+    float[] points;
+    
+    /** The point's type buffer size. */
+    int typeSize;
+    
+    /** The points buffer size. */
+    int pointSize;
+    
+    /** The path rule. */
+    int rule;
+
+    /** The space amount in points buffer for different segmenet's types. */
+    static int pointShift[] = {
+            2,  // MOVETO
+            2,  // LINETO
+            4,  // QUADTO
+            6,  // CUBICTO
+            0}; // CLOSE
+
+    /*
+     * GeneralPath path iterator 
+     */
+    /**
+     * The Class Iterator is the subclass of Iterator for traversing the 
+     * outline of a GeneralPath.
+     */
+    class Iterator implements PathIterator {
+
+        /** The current cursor position in types buffer. */
+        int typeIndex;
+        
+        /** The current cursor position in points buffer. */
+        int pointIndex;
+        
+        /** The source GeneralPath object. */
+        GeneralPath p;
+        
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /**
+         * Constructs a new GeneralPath.Iterator for given general path
+         * 
+         * @param path - the source GeneralPath object
+         */
+        Iterator(GeneralPath path) {
+            this(path, null);
+        }
+
+        /**
+         * Constructs a new GeneralPath.Iterator for given general path and transformation
+         * 
+         * @param path - the source GeneralPath object
+         * @param at - the AffineTransform object to apply rectangle path
+         */
+        Iterator(GeneralPath path, AffineTransform at) {
+            this.p = path;
+            this.t = at;
+        }
+
+        public int getWindingRule() {
+            return p.getWindingRule();
+        }
+
+        public boolean isDone() {
+            return typeIndex >= p.typeSize;
+        }
+
+        public void next() {
+            typeIndex++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = p.types[typeIndex];
+            int count = GeneralPath.pointShift[type];
+            for (int i = 0; i < count; i++) {
+                coords[i] = p.points[pointIndex + i];
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count / 2);
+            }
+            pointIndex += count;
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = p.types[typeIndex];
+            int count = GeneralPath.pointShift[type];
+            System.arraycopy(p.points, pointIndex, coords, 0, count);
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count / 2);
+            }
+            pointIndex += count;
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new general path with the winding rule set 
+     * to {@link PathIterator#WIND_NON_ZERO} and the initial capacity
+     * (number of segments) set to the default value 10.
+     */
+    public GeneralPath() {
+        this(WIND_NON_ZERO, BUFFER_SIZE);
+    }
+
+    /**
+     * Instantiates a new general path with the given winding rule
+     *  and the initial capacity (number of segments) set to the 
+     *  default value 10.
+     * 
+     * @param rule the winding rule, either {@link PathIterator#WIND_EVEN_ODD}
+     * or {@link PathIterator#WIND_NON_ZERO}
+     */
+    public GeneralPath(int rule) {
+        this(rule, BUFFER_SIZE);
+    }
+
+    /**
+     * Instantiates a new general path with the given winding rule
+     * and initial capacity (number of segments).
+     * 
+     * @param rule the winding rule, either {@link PathIterator#WIND_EVEN_ODD}
+     * or {@link PathIterator#WIND_NON_ZERO}
+     * @param initialCapacity the number of segments the path is set to hold
+     */
+    public GeneralPath(int rule, int initialCapacity) {
+        setWindingRule(rule);
+        types = new byte[initialCapacity];
+        points = new float[initialCapacity * 2];
+    }
+
+    /**
+     * Creates a new GeneralPath from the outline of the given shape.
+     * 
+     * @param shape the shape
+     */
+    public GeneralPath(Shape shape) {
+        this(WIND_NON_ZERO, BUFFER_SIZE);
+        PathIterator p = shape.getPathIterator(null);
+        setWindingRule(p.getWindingRule());
+        append(p, false);
+    }
+
+    /**
+     * Sets the winding rule, which determines how to decide whether 
+     * a point that isn't on the path itself is inside or outside of 
+     * the shape.
+     * 
+     * @param rule the new winding rule
+     * 
+     * @throws IllegalArgumentException if the winding rule is neither
+     * {@link PathIterator#WIND_EVEN_ODD} nor {@link PathIterator#WIND_NON_ZERO}.
+     */
+    public void setWindingRule(int rule) {
+        if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) {
+            // awt.209=Invalid winding rule value
+            throw new java.lang.IllegalArgumentException(Messages.getString("awt.209")); //$NON-NLS-1$
+        }
+        this.rule = rule;
+    }
+
+    /**
+     * Gets the winding rule.
+     * 
+     * @return the winding rule, either {@link PathIterator#WIND_EVEN_ODD}
+     * or {@link PathIterator#WIND_NON_ZERO}
+     */
+    public int getWindingRule() {
+        return rule;
+    }
+
+    /**
+     * Checks the point data buffer sizes to see whether pointCount additional
+     * point-data elements can fit. (Note that the number of point data 
+     * elements to add is more than one per point -- it depends on the type 
+     * of point being added.) Reallocates the buffers to enlarge the size if necessary.
+     * 
+     * @param pointCount - the number of point data elements to be added
+     * @param checkMove whether to check for existing points
+     * 
+     * @throws IllegalPathStateException checkMove is true and the 
+     * path is currently empty.
+     */
+    void checkBuf(int pointCount, boolean checkMove) {
+        if (checkMove && typeSize == 0) {
+            // awt.20A=First segment should be SEG_MOVETO type
+            throw new IllegalPathStateException(Messages.getString("awt.20A")); //$NON-NLS-1$
+        }
+        if (typeSize == types.length) {
+            byte tmp[] = new byte[typeSize + BUFFER_CAPACITY];
+            System.arraycopy(types, 0, tmp, 0, typeSize);
+            types = tmp;
+        }
+        if (pointSize + pointCount > points.length) {
+            float tmp[] = new float[pointSize + Math.max(BUFFER_CAPACITY * 2, pointCount)];
+            System.arraycopy(points, 0, tmp, 0, pointSize);
+            points = tmp;
+        }
+    }
+
+    /**
+     * Appends a new point to the end of this general path, disconnected
+     * from the existing path.
+     * 
+     * @param x the x coordinate of the next point to append
+     * @param y the y coordinate of the next point to append
+     */
+    public void moveTo(float x, float y) {
+        if (typeSize > 0 && types[typeSize - 1] == PathIterator.SEG_MOVETO) {
+            points[pointSize - 2] = x;
+            points[pointSize - 1] = y;
+        } else {
+            checkBuf(2, false);
+            types[typeSize++] = PathIterator.SEG_MOVETO;
+            points[pointSize++] = x;
+            points[pointSize++] = y;
+        }
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making 
+     * a straight line segment from the current endpoint to the 
+     * given new point.
+     * 
+     * @param x the x coordinate of the next point to append
+     * @param y the y coordinate of the next point to append
+     */
+    public void lineTo(float x, float y) {
+        checkBuf(2, true);
+        types[typeSize++] = PathIterator.SEG_LINETO;
+        points[pointSize++] = x;
+        points[pointSize++] = y;
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making 
+     * a quadratic curve from the current endpoint to the point (x2, y2)
+     * using the point (x1, y1) as the quadratic curve's control point.
+     * 
+     * @param x1 the x coordinate of the quadratic curve's control point
+     * @param y1 the y coordinate of the quadratic curve's control point
+     * @param x2 the x coordinate of the quadratic curve's end point
+     * @param y2 the y coordinate of the quadratic curve's end point
+     */
+    public void quadTo(float x1, float y1, float x2, float y2) {
+        checkBuf(4, true);
+        types[typeSize++] = PathIterator.SEG_QUADTO;
+        points[pointSize++] = x1;
+        points[pointSize++] = y1;
+        points[pointSize++] = x2;
+        points[pointSize++] = y2;
+    }
+
+    /**
+     * Appends a new segment to the end of this general path by making 
+     * a cubic curve from the current endpoint to the point (x3, y3)
+     * using (x1, y1) and (x2, y2) as control points.
+     * 
+     * @see java.awt.geom.CubicCurve2D
+     * 
+     * @param x1 the x coordinate of the new cubic segment's first control point
+     * @param y1 the y coordinate of the new cubic segment's first control point
+     * @param x2 the x coordinate of the new cubic segment's second control point
+     * @param y2 the y coordinate of the new cubic segment's second control point
+     * @param x3 the x coordinate of the new cubic segment's end point
+     * @param y3 the y coordinate of the new cubic segment's end point
+     */
+    public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) {
+        checkBuf(6, true);
+        types[typeSize++] = PathIterator.SEG_CUBICTO;
+        points[pointSize++] = x1;
+        points[pointSize++] = y1;
+        points[pointSize++] = x2;
+        points[pointSize++] = y2;
+        points[pointSize++] = x3;
+        points[pointSize++] = y3;
+    }
+
+    /**
+     * Appends the type information to declare that the current
+     * endpoint closes the curve.
+     */
+    public void closePath() {
+        if (typeSize == 0 || types[typeSize - 1] != PathIterator.SEG_CLOSE) {
+            checkBuf(0, true);
+            types[typeSize++] = PathIterator.SEG_CLOSE;
+        }
+    }
+
+    /**
+     * Appends the outline of the specified shape onto the end 
+     * of this GeneralPath.
+     * 
+     * @param shape the shape whose outline is to be appended
+     * @param connect true to connect this path's current 
+     * endpoint to the first point of the shape's outline or 
+     * false to append the shape's outline without connecting it
+     * 
+     * @throws NullPointerException if the shape parameter is null
+     */
+    public void append(Shape shape, boolean connect) {
+        PathIterator p = shape.getPathIterator(null);
+        append(p, connect);
+    }
+
+    /**
+     * Appends the path defined by the specified PathIterator onto the end 
+     * of this GeneralPath.
+     * 
+     * @param path the PathIterator that defines the new path to append
+     * @param connect true to connect this path's current 
+     * endpoint to the first point of the shape's outline or 
+     * false to append the shape's outline without connecting it
+     */
+    public void append(PathIterator path, boolean connect) {
+        while (!path.isDone()) {
+            float coords[] = new float[6];
+            switch (path.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (!connect || typeSize == 0) {
+                    moveTo(coords[0], coords[1]);
+                    break;
+                }
+                if (types[typeSize - 1] != PathIterator.SEG_CLOSE &&
+                    points[pointSize - 2] == coords[0] &&
+                    points[pointSize - 1] == coords[1])
+                {
+                    break;
+                }
+            // NO BREAK;
+            case PathIterator.SEG_LINETO:
+                lineTo(coords[0], coords[1]);
+                break;
+            case PathIterator.SEG_QUADTO:
+                quadTo(coords[0], coords[1], coords[2], coords[3]);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
+                break;
+            case PathIterator.SEG_CLOSE:
+                closePath();
+                break;
+            }
+            path.next();
+            connect = false;
+        }
+    }
+
+    /**
+     * Gets the current end point of the path.
+     * 
+     * @return the current end point of the path
+     */
+    public Point2D getCurrentPoint() {
+        if (typeSize == 0) {
+            return null;
+        }
+        int j = pointSize - 2;
+        if (types[typeSize - 1] == PathIterator.SEG_CLOSE) {
+
+            for (int i = typeSize - 2; i > 0; i--) {
+                int type = types[i];
+                if (type == PathIterator.SEG_MOVETO) {
+                    break;
+                }
+                j -= pointShift[type];
+            }
+        }
+        return new Point2D.Float(points[j], points[j + 1]);
+    }
+
+    /**
+     * Resets the GeneralPath to being an empty path. The underlying
+     * point and segment data is not deleted but rather the end indices
+     * of the data arrays are set to zero.
+     */
+    public void reset() {
+        typeSize = 0;
+        pointSize = 0;
+    }
+
+    /**
+     * Transform all of the coordinates of this path according to the
+     * specified AffineTransform.
+     * 
+     * @param t the AffineTransform
+     */
+    public void transform(AffineTransform t) {
+        t.transform(points, 0, points, 0, pointSize / 2);
+    }
+
+    /**
+     * Creates a new GeneralPath whose data is given by this path's 
+     * data transformed according to the specified AffineTransform.
+     * 
+     * @param t the AffineTransform
+     * 
+     * @return the new GeneralPath whose data is given by this path's 
+     * data transformed according to the specified AffineTransform
+     */
+    public Shape createTransformedShape(AffineTransform t) {
+        GeneralPath p = (GeneralPath)clone();
+        if (t != null) {
+            p.transform(t);
+        }
+        return p;
+    }
+
+    public Rectangle2D getBounds2D() {
+        float rx1, ry1, rx2, ry2;
+        if (pointSize == 0) {
+            rx1 = ry1 = rx2 = ry2 = 0.0f;
+        } else {
+            int i = pointSize - 1;
+            ry1 = ry2 = points[i--];
+            rx1 = rx2 = points[i--];
+            while (i > 0) {
+                float y = points[i--];
+                float x = points[i--];
+                if (x < rx1) {
+                    rx1 = x;
+                } else
+                    if (x > rx2) {
+                        rx2 = x;
+                    }
+                if (y < ry1) {
+                    ry1 = y;
+                } else
+                    if (y > ry2) {
+                        ry2 = y;
+                    }
+            }
+        }
+        return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    /**
+     * Checks the cross count (number of times a ray from the point 
+     * crosses the shape's boundary) to determine whether the number 
+     * of crossings corresponds to a point inside the shape or not
+     * (according to the shape's path rule).
+     * 
+     * @param cross - the point's cross count
+     * 
+     * @return true if the point is inside the path, or false otherwise
+     */
+    boolean isInside(int cross) {
+        if (rule == WIND_NON_ZERO) {
+            return Crossing.isInsideNonZero(cross);
+        }
+        return Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(double px, double py) {
+        return isInside(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && isInside(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || isInside(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            GeneralPath p = (GeneralPath) super.clone();
+            p.types = types.clone();
+            p.points = points.clone();
+            return p;
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/geom/IllegalPathStateException.java b/awt/java/awt/geom/IllegalPathStateException.java
new file mode 100644
index 0000000..7f459e7
--- /dev/null
+++ b/awt/java/awt/geom/IllegalPathStateException.java
@@ -0,0 +1,50 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Class IllegalPathStateException indicates errors where the 
+ * current state of a path object is imcompatible with the desired 
+ * action, such as performing non-trivial actions on an empty path.
+ */
+public class IllegalPathStateException extends RuntimeException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -5158084205220481094L;
+
+    /**
+     * Instantiates a new illegal path state exception.
+     */
+    public IllegalPathStateException() {
+    }
+
+    /**
+     * Instantiates a new illegal path state exception with the 
+     * specified detail message.
+     * 
+     * @param s the details of the error
+     */
+    public IllegalPathStateException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Line2D.java b/awt/java/awt/geom/Line2D.java
new file mode 100644
index 0000000..a53c470
--- /dev/null
+++ b/awt/java/awt/geom/Line2D.java
@@ -0,0 +1,871 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class Line2D represents a line whose data is given in 
+ * high-precision values appropriate for graphical operations.
+ */
+public abstract class Line2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of Line2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends Line2D {
+
+        /** The x coordinate of the starting point. */
+        public float x1;
+        
+        /** The y coordinate of the starting point. */
+        public float y1;
+        
+        /** The x coordinate of the end point. */
+        public float x2;
+        
+        /** The y coordinate of the end point. */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued Line2D with
+         * its data values set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Float(float x1, float y1, float x2, float y2) {
+            setLine(x1, y1, x2, y2);
+        }
+
+        /**
+         * Instantiates a new float-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param p1 the starting point
+         * @param p2 the end point
+         */
+        public Float(Point2D p1, Point2D p2) {
+            setLine(p1, p2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setLine(double x1, double y1, double x2, double y2) {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values that define the line.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public void setLine(float x1, float y1, float x2, float y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx, ry, rw, rh;
+            if (x1 < x2) {
+                rx = x1;
+                rw = x2 - x1;
+            } else {
+                rx = x2;
+                rw = x1 - x2;
+            }
+            if (y1 < y2) {
+                ry = y1;
+                rh = y2 - y1;
+            } else {
+                ry = y2;
+                rh = y1 - y2;
+            }
+            return new Rectangle2D.Float(rx, ry, rw, rh);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Line2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends Line2D {
+
+        /** The x coordinate of the starting point. */
+        public double x1;
+        
+        /** The y coordinate of the starting point. */
+        public double y1;
+        
+        /** The x coordinate of the end point. */
+        public double x2;
+        
+        /** The y coordinate of the end point. */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued  Line2D with
+         * its data values set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param x1 the x coordinate of the starting point
+         * @param y1 the y coordinate of the starting point
+         * @param x2 the x coordinate of the end point
+         * @param y2 the y coordinate of the end point
+         */
+        public Double(double x1, double y1, double x2, double y2) {
+            setLine(x1, y1, x2, y2);
+        }
+
+        /**
+         * Instantiates a new double-valued Line2D with
+         * the specified endpoints.
+         * 
+         * @param p1 the starting point
+         * @param p2 the end point
+         */
+        public Double(Point2D p1, Point2D p2) {
+            setLine(p1, p2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setLine(double x1, double y1, double x2, double y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx, ry, rw, rh;
+            if (x1 < x2) {
+                rx = x1;
+                rw = x2 - x1;
+            } else {
+                rx = x2;
+                rw = x1 - x2;
+            }
+            if (y1 < y2) {
+                ry = y1;
+                rh = y2 - y1;
+            } else {
+                ry = y2;
+                rh = y1 - y2;
+            }
+            return new Rectangle2D.Double(rx, ry, rw, rh);
+        }
+    }
+
+    /*
+     * Line2D path iterator 
+     */
+    /**
+     * The subclass of PathIterator to traverse a Line2D.
+     */
+    class Iterator implements PathIterator {
+
+        /** The x coordinate of the start line point. */
+        double x1;
+        
+        /** The y coordinate of the start line point. */
+        double y1;
+        
+        /** The x coordinate of the end line point. */
+        double x2;
+        
+        /** The y coordinate of the end line point. */
+        double y2;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new Line2D.Iterator for given line and transformation
+         * 
+         * @param l - the source Line2D object
+         * @param at - the AffineTransform object to apply rectangle path
+         */
+        Iterator(Line2D l, AffineTransform at) {
+            this.x1 = l.getX1();
+            this.y1 = l.getY1();
+            this.x2 = l.getX2();
+            this.y2 = l.getY2();
+            this.t = at;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 1;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = x1;
+                coords[1] = y1;
+            } else {
+                type = SEG_LINETO;
+                coords[0] = x2;
+                coords[1] = y2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)x1;
+                coords[1] = (float)y1;
+            } else {
+                type = SEG_LINETO;
+                coords[0] = (float)x2;
+                coords[1] = (float)y2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new Line2D.
+     */
+    protected Line2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x2
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the p the starting point.
+     * 
+     * @return the p the starting point
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the p end point.
+     * 
+     * @return the p end point
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the line's endpoints.
+     * 
+     * @param x1 the x coordinate of the starting point
+     * @param y1 the y coordinate of the starting point
+     * @param x2 the x coordinate of the end point
+     * @param y2 the y coordinate of the end point
+     */
+    public abstract void setLine(double x1, double y1, double x2, double y2);
+
+    /**
+     * Sets the line's endpoints.
+     * 
+     * @param p1 the starting point
+     * @param p2 the end point
+     */
+    public void setLine(Point2D p1, Point2D p2) {
+        setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the line's endpoints by copying the data from another Line2D.
+     * 
+     * @param line the Line2D to copy the endpoint data from
+     */
+    public void setLine(Line2D line) {
+        setLine(line.getX1(), line.getY1(), line.getX2(), line.getY2());
+    }
+
+    public Rectangle getBounds() {
+    return getBounds2D().getBounds();
+    }
+
+    /**
+     * Tells where the point is with respect to the line segment, 
+     * given the orientation of the line segment. If the ray 
+     * found by extending the line segment from its starting point 
+     * is rotated, this method tells whether the ray
+     * should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the 
+     * point is on the line segment, it's 1 if the point is on the ray 
+     * or if the ray should rotate in a counter-clockwise direction to get to the
+     * point, and it's -1 if the ray should rotate in a clockwise 
+     * direction to get to the point or if the point is on the line 
+     * determined by the line segment but not on the ray from the 
+     * segment's starting point and through its end point.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the p coordinate of the test point
+     * 
+     * @return the value that describes where the point is with respect to the line segment, 
+     * given the orientation of the line segment
+     */
+    public static int relativeCCW(double x1, double y1, double x2, double y2, double px, double py) {
+        /*
+         * A = (x2-x1, y2-y1) P = (px-x1, py-y1)
+         */
+        x2 -= x1;
+        y2 -= y1;
+        px -= x1;
+        py -= y1;
+        double t = px * y2 - py * x2; // PxA
+        if (t == 0.0) {
+            t = px * x2 + py * y2; // P*A
+            if (t > 0.0) {
+                px -= x2; // B-A
+                py -= y2;
+                t = px * x2 + py * y2; // (P-A)*A
+                if (t < 0.0) {
+                    t = 0.0;
+                }
+            }
+        }
+
+        return t < 0.0 ? -1 : (t > 0.0 ? 1 : 0);
+    }
+
+    /**
+     * Tells where the point is with respect to this line segment, 
+     * given the orientation of this line segment. If the ray 
+     * found by extending the line segment from its starting point 
+     * is rotated, this method tells whether the ray
+     * should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the 
+     * point is on the line segment, it's 1 if the point is on the ray 
+     * or if the ray should rotate in a counter-clockwise direction to get to the
+     * point, and it's -1 if the ray should rotate in a clockwise 
+     * direction to get to the point or if the point is on the line 
+     * determined by the line segment but not on the ray from the 
+     * segment's starting point and through its end point.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the p coordinate of the test point
+     * 
+     * @return the value that describes where the point is with respect to 
+     * this line segment, given the orientation of this line segment
+     */
+    public int relativeCCW(double px, double py) {
+        return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Tells where the point is with respect to this line segment, 
+     * given the orientation of this line segment. If the ray 
+     * found by extending the line segment from its starting point 
+     * is rotated, this method tells whether the ray
+     * should rotate in a clockwise direction or a counter-clockwise
+     * direction to hit the point first. The return value is 0 if the 
+     * point is on the line segment, it's 1 if the point is on the ray 
+     * or if the ray should rotate in a counter-clockwise direction to get to the
+     * point, and it's -1 if the ray should rotate in a clockwise 
+     * direction to get to the point or if the point is on the line 
+     * determined by the line segment but not on the ray from the 
+     * segment's starting point and through its end point.
+     * 
+     * @param p the test point
+     * 
+     * @return the value that describes where the point is with respect to 
+     * this line segment, given the orientation of this line segment
+     */
+    public int relativeCCW(Point2D p) {
+        return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Tells whether the two line segments cross.
+     * 
+     * @param x1 the x coordinate of the starting point of the first segment
+     * @param y1 the y coordinate of the starting point of the first segment
+     * @param x2 the x coordinate of the end point of the first segment
+     * @param y2 the y coordinate of the end point of the first segment
+     * @param x3 the x coordinate of the starting point of the second segment
+     * @param y3 the y coordinate of the starting point of the second segment
+     * @param x4 the x coordinate of the end point of the second segment
+     * @param y4 the y coordinate of the end point of the second segment
+     * 
+     * @return true, if the two line segments cross
+     */
+    public static boolean linesIntersect(double x1, double y1, double x2,
+            double y2, double x3, double y3, double x4, double y4)
+    {
+        /*
+         * A = (x2-x1, y2-y1) B = (x3-x1, y3-y1) C = (x4-x1, y4-y1) D = (x4-x3,
+         * y4-y3) = C-B E = (x1-x3, y1-y3) = -B F = (x2-x3, y2-y3) = A-B
+         *
+         * Result is ((AxB) * (AxC) <=0) and ((DxE) * (DxF) <= 0)
+         *
+         * DxE = (C-B)x(-B) = BxB-CxB = BxC DxF = (C-B)x(A-B) = CxA-CxB-BxA+BxB =
+         * AxB+BxC-AxC
+         */
+
+        x2 -= x1; // A
+        y2 -= y1;
+        x3 -= x1; // B
+        y3 -= y1;
+        x4 -= x1; // C
+        y4 -= y1;
+
+        double AvB = x2 * y3 - x3 * y2;
+        double AvC = x2 * y4 - x4 * y2;
+
+        // Online
+        if (AvB == 0.0 && AvC == 0.0) {
+            if (x2 != 0.0) {
+                return
+                    (x4 * x3 <= 0.0) ||
+                    ((x3 * x2 >= 0.0) &&
+                     (x2 > 0.0 ? x3 <= x2 || x4 <= x2 : x3 >= x2 || x4 >= x2));
+            }
+            if (y2 != 0.0) {
+                return
+                    (y4 * y3 <= 0.0) ||
+                    ((y3 * y2 >= 0.0) &&
+                     (y2 > 0.0 ? y3 <= y2 || y4 <= y2 : y3 >= y2 || y4 >= y2));
+            }
+            return false;
+        }
+
+        double BvC = x3 * y4 - x4 * y3;
+
+        return (AvB * AvC <= 0.0) && (BvC * (AvB + BvC - AvC) <= 0.0);
+    }
+
+    /**
+     * Tells whether the specified line segments crosses this line segment.
+     * 
+     * @param x1 the x coordinate of the starting point of the test segment
+     * @param y1 the y coordinate of the starting point of the test segment
+     * @param x2 the x coordinate of the end point of the test segment
+     * @param y2 the y coordinate of the end point of the test segment
+     * 
+     * @return true, if the specified line segments crosses this line segment
+     */
+    public boolean intersectsLine(double x1, double y1, double x2, double y2) {
+        return linesIntersect(x1, y1, x2, y2, getX1(), getY1(), getX2(), getY2());
+    }
+
+    /**
+     * Tells whether the specified line segments crosses this line segment.
+     * 
+     * @param l the test segment
+     * 
+     * @return true, if the specified line segments crosses this line segment
+     * 
+     * @throws NullPointerException if l is null
+     */
+    public boolean intersectsLine(Line2D l) {
+        return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(), getX1(), getY1(), getX2(), getY2());
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line segment.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the the square of the distance between the point and the 
+     * line segment
+     */
+    public static double ptSegDistSq(double x1, double y1, double x2, double y2, double px, double py) {
+        /*
+         * A = (x2 - x1, y2 - y1) P = (px - x1, py - y1)
+         */
+        x2 -= x1; // A = (x2, y2)
+        y2 -= y1;
+        px -= x1; // P = (px, py)
+        py -= y1;
+        double dist;
+        if (px * x2 + py * y2 <= 0.0) { // P*A
+            dist = px * px + py * py;
+        } else {
+            px = x2 - px; // P = A - P = (x2 - px, y2 - py)
+            py = y2 - py;
+            if (px * x2 + py * y2 <= 0.0) { // P*A
+                dist = px * px + py * py;
+            } else {
+                dist = px * y2 - py * x2;
+                dist = dist * dist / (x2 * x2 + y2 * y2); // pxA/|A|
+            }
+        }
+        if (dist < 0) {
+            dist = 0;
+        }
+        return dist;
+    }
+
+    /**
+     * Gives the distance between the point and the 
+     * line segment.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the the distance between the point and the 
+     * line segment
+     */
+    public static double ptSegDist(double x1, double y1, double x2, double y2, double px, double py) {
+        return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
+    }
+
+    /**
+     * Gives the square of the distance between the point and this 
+     * line segment.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the the square of the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDistSq(double px, double py) {
+        return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the square of the distance between the point and this 
+     * line segment.
+     * 
+     * @param p the test point
+     * 
+     * @return the square of the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDistSq(Point2D p) {
+        return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the distance between the point and this 
+     * line segment.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDist(double px, double py) {
+        return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the distance between the point and this 
+     * line segment.
+     * 
+     * @param p the test point
+     * 
+     * @return the distance between the point and this 
+     * line segment
+     */
+    public double ptSegDist(Point2D p) {
+        return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line
+     */
+    public static double ptLineDistSq(double x1, double y1, double x2, double y2, double px, double py) {
+        x2 -= x1;
+        y2 -= y1;
+        px -= x1;
+        py -= y1;
+        double s = px * y2 - py * x2;
+        return s * s / (x2 * x2 + y2 * y2);
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line.
+     * 
+     * @param x1 the x coordinate of the starting point of the line segment
+     * @param y1 the y coordinate of the starting point of the line segment
+     * @param x2 the x coordinate of the end point of the line segment
+     * @param y2 the y coordinate of the end point of the line segment
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line
+     */
+    public static double ptLineDist(double x1, double y1, double x2, double y2, double px, double py) {
+        return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDistSq(double px, double py) {
+        return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the square of the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param p the test point
+     * 
+     * @return the square of the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDistSq(Point2D p) {
+        return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    /**
+     * Gives the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param px the x coordinate of the test point
+     * @param py the y coordinate of the test point
+     * 
+     * @return the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDist(double px, double py) {
+        return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
+    }
+
+    /**
+     * Gives the distance between the point and the 
+     * line determined by this Line2D.
+     * 
+     * @param p the test point
+     * 
+     * @return the distance between the point and the 
+     * line determined by this Line2D
+     */
+    public double ptLineDist(Point2D p) {
+        return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
+    }
+
+    public boolean contains(double px, double py) {
+        return false;
+    }
+
+    public boolean contains(Point2D p) {
+        return false;
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return false;
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        return false;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        return intersects(new Rectangle2D.Double(rx, ry, rw, rh));
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return r.intersectsLine(getX1(), getY1(), getX2(), getY2());
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at, double flatness) {
+        return new Iterator(this, at);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
diff --git a/awt/java/awt/geom/NoninvertibleTransformException.java b/awt/java/awt/geom/NoninvertibleTransformException.java
new file mode 100644
index 0000000..2b7b542
--- /dev/null
+++ b/awt/java/awt/geom/NoninvertibleTransformException.java
@@ -0,0 +1,43 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Class NoninvertibleTransformException is the exception that is thrown 
+ * when an action requires inverting an {@link AffineTransform} that is 
+ * not invertible (has determinant 0).
+ */
+public class NoninvertibleTransformException extends java.lang.Exception {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 6137225240503990466L;
+
+    /**
+     * Instantiates a new noninvertible transform exception.
+     * 
+     * @param s the error message
+     */
+    public NoninvertibleTransformException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/geom/PathIterator.java b/awt/java/awt/geom/PathIterator.java
new file mode 100644
index 0000000..5a98083
--- /dev/null
+++ b/awt/java/awt/geom/PathIterator.java
@@ -0,0 +1,132 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+/**
+ * The Interface PathIterator represents an iterator object that can 
+ * be used to traverse the outline of a {@link java.awt.Shape}. 
+ * It returns points along the boundary of the Shape 
+ * which may be actual vertices (in the case of a shape made of line 
+ * segments) or may be points on a curved segment with the distance 
+ * between the points determined by a chosen flattening factor. 
+ * <p>
+ * If the shape is closed, the outline is traversed in the counter-clockwise 
+ * direction. That means that moving forward along the boundary is to travel 
+ * in such a way that the interior of the shape is to the left of the 
+ * outline path and the exterior of the shape is to the right of the outline
+ * path. The interior and exterior of the shape are determined by a 
+ * winding rule. 
+ */
+public interface PathIterator {
+
+    /** The Constant WIND_EVEN_ODD indicates the winding rule that says 
+     * that a point is outside the shape if any infinite ray from the point 
+     * crosses the outline of the shape an even number of times, otherwise
+     * it is inside. */
+    public static final int WIND_EVEN_ODD = 0;
+    
+    /** The Constant WIND_NON_ZERO indicates the winding rule that says that
+     * a point is inside the shape if every infinite ray starting from that
+     * point crosses the outline of the shape a non-zero number of times. */
+    public static final int WIND_NON_ZERO = 1;
+
+    /** The Constant SEG_MOVETO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should be placed directly on the current point. */
+    public static final int SEG_MOVETO  = 0;
+    
+    /** The Constant SEG_LINETO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should follow a straight line. */
+    public static final int SEG_LINETO  = 1;
+    
+    /** The Constant SEG_QUADTO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should follow a quadratic curve. */
+    public static final int SEG_QUADTO  = 2;
+    
+    /** The Constant SEG_CUBICTO indicates that to follow the shape's outline
+     * from the previous point to the current point, the cursor (traversal 
+     * point) should follow a cubic curve. */
+    public static final int SEG_CUBICTO = 3;
+    
+    /** The Constant SEG_CLOSE indicates that the previous point was the end
+     * of the shape's outline. */
+    public static final int SEG_CLOSE   = 4;
+
+    /**
+     * Gets the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
+     * {@link PathIterator#WIND_NON_ZERO}.
+     * 
+     * @return the winding rule
+     */
+    public int getWindingRule();
+
+    /**
+     * Checks if this PathIterator has been completely traversed.
+     * 
+     * @return true, if this PathIterator has been completely traversed
+     */
+    public boolean isDone();
+
+    /**
+     * Tells this PathIterator to skip to the next segment.
+     */
+    public void next();
+
+    /**
+     * Gets the coordinates of the next vertex point along the shape's outline 
+     * and a flag that indicates what kind of segment to use in order to 
+     * connect the previous vertex point to the current vertex point to form 
+     * the current segment.
+     * 
+     * @param coords the array that the coordinates of the end point of the current 
+     * segment are written into.
+     * 
+     * @return the flag that indicates how to follow the shape's outline
+     * from the previous point to the current one, chosen from 
+     * the following constants:
+     * {@link PathIterator#SEG_MOVETO}, {@link PathIterator#SEG_LINETO}, 
+     * {@link PathIterator#SEG_QUADTO}, {@link PathIterator#SEG_CUBICTO}, 
+     * or {@link PathIterator#SEG_CLOSE}
+     */
+    public int currentSegment(float[] coords);
+
+    /**
+     * Gets the coordinates of the next vertex point along the shape's outline 
+     * and a flag that indicates what kind of segment to use in order to 
+     * connect the previous vertex point to the current vertex point to form 
+     * the current segment.
+     * 
+     * @param coords the array that the coordinates of the end point of the current 
+     * segment are written into.
+     * 
+     * @return the flag that indicates how to follow the shape's outline
+     * from the previous point to the current one, chosen from 
+     * the following constants:
+     * {@link PathIterator#SEG_MOVETO}, {@link PathIterator#SEG_LINETO}, 
+     * {@link PathIterator#SEG_QUADTO}, {@link PathIterator#SEG_CUBICTO}, 
+     * or {@link PathIterator#SEG_CLOSE}
+     */
+    public int currentSegment(double[] coords);
+
+}
+
diff --git a/awt/java/awt/geom/Point2D.java b/awt/java/awt/geom/Point2D.java
new file mode 100644
index 0000000..7719e67
--- /dev/null
+++ b/awt/java/awt/geom/Point2D.java
@@ -0,0 +1,288 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class Point2D represents a point whose data is given in 
+ * high-precision values appropriate for graphical operations.
+ */
+public abstract class Point2D implements Cloneable {
+
+    /**
+     * The Class Float is the subclass of Point2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends Point2D {
+
+        /** The x coordinate. */
+        public float x;
+        
+        /** The y coordinate. */
+        public float y;
+
+        /**
+         * Instantiates a new float-valued Point2D with its data 
+         * set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued Point2D with the specified coordinates.
+         * 
+         * @param x the x coordinate
+         * @param y the y coordinate
+         */
+        public Float(float x, float y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        /**
+         * Sets the point's coordinates.
+         * 
+         * @param x the x coordinate
+         * @param y the y coordinate
+         */
+        public void setLocation(float x, float y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public void setLocation(double x, double y) {
+            this.x = (float)x;
+            this.y = (float)y;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Point2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends Point2D {
+
+        /** The x coordinate. */
+        public double x;
+        
+        /** The y coordinate. */
+        public double y;
+
+        /**
+         * Instantiates a new double-valued Point2D with its data 
+         * set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued Point2D with the specified coordinates.
+         * 
+         * @param x the x coordinate
+         * @param y the y coordinate
+         */
+        public Double(double x, double y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public void setLocation(double x, double y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+    }
+
+    /**
+     * Instantiates a new Point2D.
+     */
+    protected Point2D() {
+    }
+
+    /**
+     * Gets the x coordinate.
+     * 
+     * @return the x coordinate
+     */
+    public abstract double getX();
+
+    /**
+     * Gets the y coordinate.
+     * 
+     * @return the y coordinate
+     */
+    public abstract double getY();
+
+    /**
+     * Sets the point's coordinates.
+     * 
+     * @param x the x coordinate
+     * @param y the y coordinate
+     */
+    public abstract void setLocation(double x, double y);
+
+    /**
+     * Sets the point's coordinates by copying them from another point.
+     * 
+     * @param p the point to copy the data from
+     */
+    public void setLocation(Point2D p) {
+        setLocation(p.getX(), p.getY());
+    }
+
+    /**
+     * Finds the square of the distance between the two specified points.
+     * 
+     * @param x1 the x coordinate of the first point
+     * @param y1 the y coordinate of the first point
+     * @param x2 the x coordinate of the second point
+     * @param y2 the y coordinate of the second point
+     * 
+     * @return the square of the distance between the two specified points
+     */
+    public static double distanceSq(double x1, double y1, double x2, double y2) {
+        x2 -= x1;
+        y2 -= y1;
+        return x2 * x2 + y2 * y2;
+    }
+
+    /**
+     * Finds the square of the distance between this point and the specified point.
+     * 
+     * @param px the x coordinate of the point
+     * @param py the y coordinate of the point
+     * 
+     * @return the square of the distance between this point and the specified point
+     */
+    public double distanceSq(double px, double py) {
+        return Point2D.distanceSq(getX(), getY(), px, py);
+    }
+
+    /**
+     * Finds the square of the distance between this point and the specified point.
+     * 
+     * @param p the other point
+     * 
+     * @return the square of the distance between this point and the specified point
+     */
+    public double distanceSq(Point2D p) {
+        return Point2D.distanceSq(getX(), getY(), p.getX(), p.getY());
+    }
+
+    /**
+     * Finds the distance between the two specified points.
+     * 
+     * @param x1 the x coordinate of the first point
+     * @param y1 the y coordinate of the first point
+     * @param x2 the x coordinate of the second point
+     * @param y2 the y coordinate of the second point
+     * 
+     * @return the distance between the two specified points
+     */
+    public static double distance(double x1, double y1, double x2, double y2) {
+        return Math.sqrt(distanceSq(x1, y1, x2, y2));
+    }
+
+    /**
+     * Finds the distance between this point and the specified point.
+     * 
+     * @param px the x coordinate of the point
+     * @param py the y coordinate of the point
+     * 
+     * @return the distance between this point and the specified point
+     */
+    public double distance(double px, double py) {
+        return Math.sqrt(distanceSq(px, py));
+    }
+
+    /**
+     * Finds the distance between this point and the specified point.
+     * 
+     * @param p the other point
+     * 
+     * @return the distance between this point and the specified point
+     */
+    public double distance(Point2D p) {
+        return Math.sqrt(distanceSq(p));
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(getX());
+        hash.append(getY());
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Point2D) {
+            Point2D p = (Point2D) obj;
+            return getX() == p.getX() && getY() == p.getY();
+        }
+        return false;
+    }
+}
+
diff --git a/awt/java/awt/geom/QuadCurve2D.java b/awt/java/awt/geom/QuadCurve2D.java
new file mode 100644
index 0000000..64ea6d6
--- /dev/null
+++ b/awt/java/awt/geom/QuadCurve2D.java
@@ -0,0 +1,824 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.gl.Crossing;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class QuadCurve2D is a Shape that represents a segment of a 
+ * quadratic (Bezier) curve. The curved segment is determined by three points:
+ * a start point, an end point, and a control point.  The line from the control 
+ * point to the starting point gives the tangent to the curve at the
+ * starting point, and the line from the control point to the end point 
+ * gives the tangent to the curve at the end point.
+ */
+public abstract class QuadCurve2D implements Shape, Cloneable {
+
+    /**
+     * The Class Float is the subclass of QuadCurve2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends QuadCurve2D {
+
+        /** The x coordinate of the starting point of the curved segment. */
+        public float x1;
+        
+        /** The y coordinate of the starting point of the curved segment. */
+        public float y1;
+        
+        /** The x coordinate of the control point.  */
+        public float ctrlx;
+        
+        /** The y coordinate of the control point. */
+        public float ctrly;
+        
+        /** The x coordinate of the end point of the curved segment. */
+        public float x2;
+        
+        /** The y coordinate of the end point of the curved segment. */
+        public float y2;
+
+        /**
+         * Instantiates a new float-valued QuadCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued QuadCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point of the curved segment
+         * @param y1 the y coordinate of the starting point of the curved segment
+         * @param ctrlx the x coordinate of the control point
+         * @param ctrly the y coordinate of the control point
+         * @param x2 the x coordinate of the end point of the curved segment
+         * @param y2 the y coordinate of the end point of the curved segment
+         */
+        public Float(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
+            setCurve(x1, y1, ctrlx, ctrly, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX() {
+            return ctrlx;
+        }
+
+        @Override
+        public double getCtrlY() {
+            return ctrly;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Float(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlPt() {
+            return new Point2D.Float(ctrlx, ctrly);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Float(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            this.x1 = (float)x1;
+            this.y1 = (float)y1;
+            this.ctrlx = (float)ctrlx;
+            this.ctrly = (float)ctrly;
+            this.x2 = (float)x2;
+            this.y2 = (float)y2;
+        }
+
+        /**
+         * Sets the data values of the curve.
+         * 
+         * @param x1 the x coordinate of the starting point of the curved segment
+         * @param y1 the y coordinate of the starting point of the curved segment
+         * @param ctrlx the x coordinate of the control point
+         * @param ctrly the y coordinate of the control point
+         * @param x2 the x coordinate of the end point of the curved segment
+         * @param y2 the y coordinate of the end point of the curved segment
+         */
+        public void setCurve(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx = ctrlx;
+            this.ctrly = ctrly;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            float rx0 = Math.min(Math.min(x1, x2), ctrlx);
+            float ry0 = Math.min(Math.min(y1, y2), ctrly);
+            float rx1 = Math.max(Math.max(x1, x2), ctrlx);
+            float ry1 = Math.max(Math.max(y1, y2), ctrly);
+            return new Rectangle2D.Float(rx0, ry0, rx1 - rx0, ry1 - ry0);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of QuadCurve2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends QuadCurve2D {
+
+        /** The x coordinate of the starting point of the curved segment. */
+        public double x1;
+        
+        /** The y coordinate of the starting point of the curved segment. */
+        public double y1;
+        
+        /** The x coordinate of the control point. */
+        public double ctrlx;
+        
+        /** The y coordinate of the control point. */
+        public double ctrly;
+        
+        /** The x coordinate of the end point of the curved segment. */
+        public double x2;
+        
+        /** The y coordinate of the end point of the curved segment. */
+        public double y2;
+
+        /**
+         * Instantiates a new double-valued QuadCurve2D with all coordinate values
+         * set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued QuadCurve2D with the specified
+         * coordinate values.
+         * 
+         * @param x1 the x coordinate of the starting point of the curved segment
+         * @param y1 the y coordinate of the starting point of the curved segment
+         * @param ctrlx the x coordinate of the control point
+         * @param ctrly the y coordinate of the control point
+         * @param x2 the x coordinate of the end point of the curved segment
+         * @param y2 the y coordinate of the end point of the curved segment
+         */
+        public Double(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            setCurve(x1, y1, ctrlx, ctrly, x2, y2);
+        }
+
+        @Override
+        public double getX1() {
+            return x1;
+        }
+
+        @Override
+        public double getY1() {
+            return y1;
+        }
+
+        @Override
+        public double getCtrlX() {
+            return ctrlx;
+        }
+
+        @Override
+        public double getCtrlY() {
+            return ctrly;
+        }
+
+        @Override
+        public double getX2() {
+            return x2;
+        }
+
+        @Override
+        public double getY2() {
+            return y2;
+        }
+
+        @Override
+        public Point2D getP1() {
+            return new Point2D.Double(x1, y1);
+        }
+
+        @Override
+        public Point2D getCtrlPt() {
+            return new Point2D.Double(ctrlx, ctrly);
+        }
+
+        @Override
+        public Point2D getP2() {
+            return new Point2D.Double(x2, y2);
+        }
+
+        @Override
+        public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.ctrlx = ctrlx;
+            this.ctrly = ctrly;
+            this.x2 = x2;
+            this.y2 = y2;
+        }
+
+        public Rectangle2D getBounds2D() {
+            double rx0 = Math.min(Math.min(x1, x2), ctrlx);
+            double ry0 = Math.min(Math.min(y1, y2), ctrly);
+            double rx1 = Math.max(Math.max(x1, x2), ctrlx);
+            double ry1 = Math.max(Math.max(y1, y2), ctrly);
+            return new Rectangle2D.Double(rx0, ry0, rx1 - rx0, ry1 - ry0);
+        }
+    }
+
+    /*
+     * QuadCurve2D path iterator 
+     */
+    /**
+     * The PathIterator for a Quad2D curve.
+     */
+    class Iterator implements PathIterator {
+
+        /** The source QuadCurve2D object. */
+        QuadCurve2D c;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segment index. */
+        int index;
+
+        /**
+         * Constructs a new QuadCurve2D.Iterator for given curve and transformation
+         * 
+         * @param q - the source QuadCurve2D object
+         * @param t the AffineTransform that acts on the coordinates before 
+         * returning them (or null)
+         */
+        Iterator(QuadCurve2D q, AffineTransform t) {
+            this.c = q;
+            this.t = t;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return (index > 1);
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = c.getX1();
+                coords[1] = c.getY1();
+                count = 1;
+            } else {
+                type = SEG_QUADTO;
+                coords[0] = c.getCtrlX();
+                coords[1] = c.getCtrlY();
+                coords[2] = c.getX2();
+                coords[3] = c.getY2();
+                count = 2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type;
+            int count;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = (float)c.getX1();
+                coords[1] = (float)c.getY1();
+                count = 1;
+            } else {
+                type = SEG_QUADTO;
+                coords[0] = (float)c.getCtrlX();
+                coords[1] = (float)c.getCtrlY();
+                coords[2] = (float)c.getX2();
+                coords[3] = (float)c.getY2();
+                count = 2;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, count);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new quadratic curve.
+     */
+    protected QuadCurve2D() {
+    }
+
+    /**
+     * Gets the x coordinate of the starting point.
+     * 
+     * @return the x coordinate of the starting point
+     */
+    public abstract double getX1();
+
+    /**
+     * Gets the y coordinate of the starting point.
+     * 
+     * @return the y coordinate of the starting point
+     */
+    public abstract double getY1();
+
+    /**
+     * Gets the starting point.
+     * 
+     * @return the starting point
+     */
+    public abstract Point2D getP1();
+
+    /**
+     * Gets the x coordinate of the control point.
+     * 
+     * @return the x coordinate of the control point
+     */
+    public abstract double getCtrlX();
+
+    /**
+     * Gets the y coordinate of the control point.
+     * 
+     * @return y coordinate of the control point
+     */
+    public abstract double getCtrlY();
+
+    /**
+     * Gets the control point.
+     * 
+     * @return the control point
+     */
+    public abstract Point2D getCtrlPt();
+
+    /**
+     * Gets the x coordinate of the end point.
+     * 
+     * @return the x coordinate of the end point
+     */
+    public abstract double getX2();
+
+    /**
+     * Gets the y coordinate of the end point.
+     * 
+     * @return the y coordinate of the end point
+     */
+    public abstract double getY2();
+
+    /**
+     * Gets the end point.
+     * 
+     * @return the end point
+     */
+    public abstract Point2D getP2();
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param x1 the x coordinate of the starting point of the curved segment
+     * @param y1 the y coordinate of the starting point of the curved segment
+     * @param ctrlx the x coordinate of the control point
+     * @param ctrly the y coordinate of the control point
+     * @param x2 the x coordinate of the end point of the curved segment
+     * @param y2 the y coordinate of the end point of the curved segment
+     */
+    public abstract void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2);
+
+    /**
+     * Sets the data of the curve.
+     * 
+     * @param p1 the starting point of the curved segment
+     * @param cp the control point
+     * @param p2 the end point of the curved segment
+     * 
+     * @throws NullPointerException if any of the three points is null.
+     */
+    public void setCurve(Point2D p1, Point2D cp, Point2D p2) {
+        setCurve(p1.getX(), p1.getY(), cp.getX(), cp.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of values. The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#setCurve(double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of values containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 6.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public void setCurve(double[] coords, int offset) {
+        setCurve(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 2], coords[offset + 3],
+                coords[offset + 4], coords[offset + 5]);
+    }
+
+    /**
+     * Sets the data of the curve by reading the data from an array
+     * of points. The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#setCurve(Point2D, Point2D, Point2D)}
+     * 
+     * @param points the array of points containing the new coordinates
+     * @param offset the offset of the data to read within the array
+     * 
+     * @throws ArrayIndexOutOfBoundsException if points.length < offset + 3.
+     * @throws NullPointerException if the point array is null.
+     */
+    public void setCurve(Point2D[] points, int offset) {
+        setCurve(
+                points[offset + 0].getX(), points[offset + 0].getY(),
+                points[offset + 1].getX(), points[offset + 1].getY(),
+                points[offset + 2].getX(), points[offset + 2].getY());
+    }
+
+    /**
+     * Sets the data of the curve by copying it from another QuadCurve2D.
+     * 
+     * @param curve the curve to copy the data points from
+     * 
+     * @throws NullPointerException if the curve is null.
+     */
+    public void setCurve(QuadCurve2D curve) {
+        setCurve(
+                curve.getX1(), curve.getY1(),
+                curve.getCtrlX(), curve.getCtrlY(),
+                curve.getX2(), curve.getY2());
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * for this curve.
+     * 
+     * @return the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     */
+    public double getFlatnessSq() {
+        return Line2D.ptSegDistSq(
+                getX1(), getY1(),
+                getX2(), getY2(),
+                getCtrlX(), getCtrlY());
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * 
+     * @param x1 the x coordinate of the starting point of the curved segment
+     * @param y1 the y coordinate of the starting point of the curved segment
+     * @param ctrlx the x coordinate of the control point
+     * @param ctrly the y coordinate of the control point
+     * @param x2 the x coordinate of the end point of the curved segment
+     * @param y2 the y coordinate of the end point of the curved segment
+     * 
+     * @return the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     */
+    public static double getFlatnessSq(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
+        return Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx, ctrly);
+    }
+
+    /**
+     * Gets the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * by reading the coordinates of the points from an array of values.
+     * The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#getFlatnessSq(double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the coordinates to use for 
+     * the calculation
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the square of the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 6.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public static double getFlatnessSq(double coords[], int offset) {
+        return Line2D.ptSegDistSq(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 2], coords[offset + 3]);
+    }
+
+    /**
+     * Gets the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * of this QuadCurve2D.
+     * 
+     * @return the the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * of this QuadCurve2D
+     */
+    public double getFlatness() {
+        return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY());
+    }
+
+    /**
+     * Gets the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * 
+     * @param x1 the x coordinate of the starting point of the curved segment
+     * @param y1 the y coordinate of the starting point of the curved segment
+     * @param ctrlx the x coordinate of the control point
+     * @param ctrly the y coordinate of the control point
+     * @param x2 the x coordinate of the end point of the curved segment
+     * @param y2 the y coordinate of the end point of the curved segment
+     * 
+     * @return the the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     */
+    public static double getFlatness(double x1, double y1, double ctrlx,
+            double ctrly, double x2, double y2)
+    {
+        return Line2D.ptSegDist(x1, y1, x2, y2, ctrlx, ctrly);
+    }
+
+    /**
+     * Gets the the distance from the control point to the
+     * straight line segment connecting the start point and the end point.
+     * The values are read in the same order as the arguments
+     * of the method {@link QuadCurve2D#getFlatness(double, double, double, double, double, double)}.
+     * 
+     * @param coords the array of points containing the coordinates to use for 
+     * the calculation
+     * @param offset the offset of the data to read within the array
+     * 
+     * @return the the distance from the control point to the
+     * straight line segment connecting the start point and the end point
+     * 
+     * @throws ArrayIndexOutOfBoundsException if coords.length < offset + 6.
+     * @throws NullPointerException if the coordinate array is null.
+     */
+    public static double getFlatness(double coords[], int offset) {
+        return Line2D.ptSegDist(
+                coords[offset + 0], coords[offset + 1],
+                coords[offset + 4], coords[offset + 5],
+                coords[offset + 2], coords[offset + 3]);
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing this
+     * curve in two. The division point is the point on the curve 
+     * that is closest to this curve's control point. The data of 
+     * this curve is left unchanged.
+     * 
+     * @param left the QuadCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the QuadCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if either curve is null.
+     */
+    public void subdivide(QuadCurve2D left, QuadCurve2D right) {
+        subdivide(this, left, right);
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing a source
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the source curve's control point. The data of 
+     * the source curve is left unchanged.
+     * 
+     * @param src the curve that provides the initial data
+     * @param left the QuadCurve2D where the left (start) segment's 
+     * data is written
+     * @param right the QuadCurve2D where the right (end) segment's 
+     * data is written
+     * 
+     * @throws NullPointerException if one of the curves is null.
+     */
+    public static void subdivide(QuadCurve2D src, QuadCurve2D left, QuadCurve2D right) {
+        double x1 = src.getX1();
+        double y1 = src.getY1();
+        double cx = src.getCtrlX();
+        double cy = src.getCtrlY();
+        double x2 = src.getX2();
+        double y2 = src.getY2();
+        double cx1 = (x1 + cx) / 2.0;
+        double cy1 = (y1 + cy) / 2.0;
+        double cx2 = (x2 + cx) / 2.0;
+        double cy2 = (y2 + cy) / 2.0;
+        cx = (cx1 + cx2) / 2.0;
+        cy = (cy1 + cy2) / 2.0;
+        if (left != null) {
+            left.setCurve(x1, y1, cx1, cy1, cx, cy);
+        }
+        if (right != null) {
+            right.setCurve(cx, cy, cx2, cy2, x2, y2);
+        }
+    }
+
+    /**
+     * Creates the data for two quadratic curves by dividing a source
+     * curve in two. The division point is the point on the curve 
+     * that is closest to the source curve's control point. The data
+     * for the three curves is read and written from arrays of values in 
+     * the usual order: x1, y1, cx, cy, x2, y2.
+     *  
+     * @param src the array that gives the data values for the source curve
+     * @param srcoff the offset in the src array to read the values from
+     * @param left the array where the coordinates of the start curve should be written
+     * @param leftOff the offset in the left array to start writing the values
+     * @param right the array where the coordinates of the end curve should be written
+     * @param rightOff the offset in the right array to start writing the values
+     * 
+     * @throws ArrayIndexOutOfBoundsException if src.length < srcoff + 6
+     * or if left.length < leftOff + 6 or if right.length < rightOff + 6.
+     * @throws NullPointerException if one of the arrays is null.
+     */
+    public static void subdivide(double src[], int srcoff, double left[],
+            int leftOff, double right[], int rightOff)
+    {
+        double x1 = src[srcoff + 0];
+        double y1 = src[srcoff + 1];
+        double cx = src[srcoff + 2];
+        double cy = src[srcoff + 3];
+        double x2 = src[srcoff + 4];
+        double y2 = src[srcoff + 5];
+        double cx1 = (x1 + cx) / 2.0;
+        double cy1 = (y1 + cy) / 2.0;
+        double cx2 = (x2 + cx) / 2.0;
+        double cy2 = (y2 + cy) / 2.0;
+        cx = (cx1 + cx2) / 2.0;
+        cy = (cy1 + cy2) / 2.0;
+        if (left != null) {
+            left[leftOff + 0] = x1;
+            left[leftOff + 1] = y1;
+            left[leftOff + 2] = cx1;
+            left[leftOff + 3] = cy1;
+            left[leftOff + 4] = cx;
+            left[leftOff + 5] = cy;
+        }
+        if (right != null) {
+            right[rightOff + 0] = cx;
+            right[rightOff + 1] = cy;
+            right[rightOff + 2] = cx2;
+            right[rightOff + 3] = cy2;
+            right[rightOff + 4] = x2;
+            right[rightOff + 5] = y2;
+        }
+    }
+
+    /**
+     * Finds the roots of the quadratic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written back into the array eqn starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been changed by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * quadratic polynomial to solve.
+     * 
+     * @return the number of roots of the quadratic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 3.
+     * @throws NullPointerException if the array is null.
+     */
+    public static int solveQuadratic(double eqn[]) {
+        return solveQuadratic(eqn, eqn);
+    }
+
+    /**
+     * Finds the roots of the quadratic polynomial. This is 
+     * accomplished by finding the (real) values of x that solve
+     * the following equation: eqn[2]*x*x + eqn[1]*x + eqn[0] = 0.
+     * The solutions are written into the array res starting
+     * from the index 0 in the array. The return value tells how 
+     * many array elements have been written by this method call.
+     * 
+     * @param eqn an array containing the coefficients of the 
+     * quadratic polynomial to solve.
+     * @param res the array that this method writes the results into
+     * 
+     * @return the number of roots of the quadratic polynomial
+     * 
+     * @throws ArrayIndexOutOfBoundsException if eqn.length < 3 or 
+     * if res.length is less than the number of roots.
+     * @throws NullPointerException if either array is null.
+     */
+    public static int solveQuadratic(double eqn[], double res[]) {
+        return Crossing.solveQuad(eqn, res);
+    }
+
+    public boolean contains(double px, double py) {
+        return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
+        return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
+    }
+
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    public boolean intersects(Rectangle2D r) {
+        return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public boolean contains(Rectangle2D r) {
+        return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        return getBounds2D().getBounds();
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/geom/Rectangle2D.java b/awt/java/awt/geom/Rectangle2D.java
new file mode 100644
index 0000000..d33dd91
--- /dev/null
+++ b/awt/java/awt/geom/Rectangle2D.java
@@ -0,0 +1,761 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+
+/**
+ * The Class Rectangle2D represents a rectangle whose coordinates are given 
+ * with the correct precision to be used with the Graphics2D classes.
+ */
+public abstract class Rectangle2D extends RectangularShape {
+
+    /** The Constant OUT_LEFT is a mask that is used to indicate that a 
+     * given point is outside the rectangle and to its left. */
+    public static final int OUT_LEFT   = 1;
+    
+    /** The Constant OUT_TOP is a mask that is used to indicate that a 
+     * given point is outside the rectangle and above it. */
+    public static final int OUT_TOP    = 2;
+    
+    /** The Constant OUT_RIGHT is a mask that is used to indicate that a 
+     * given point is outside the rectangle and to its right. */
+    public static final int OUT_RIGHT  = 4;
+    
+    /** The Constant OUT_BOTTOM is a mask that is used to indicate that a 
+     * given point is outside the rectangle and above it. */
+    public static final int OUT_BOTTOM = 8;
+
+    /**
+     * The Class Float is the subclass of Rectangle2D that represents a 
+     * rectangle whose data values are given as floats (with float-level
+     * precision).
+     */
+    public static class Float extends Rectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public float x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public float y;
+        
+        /** The width of the rectangle. */
+        public float width;
+        
+        /** The height of the rectangle. */
+        public float height;
+
+        /**
+         * Instantiates a new empty rectangle with float-precision data fields.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new rectangle with the specified float-precision data.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         */
+        public Float(float x, float y, float width, float height) {
+            setRect(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        /**
+         * Sets the rectangle's data to the given values.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         */
+        public void setRect(float x, float y, float width, float height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setRect(double x, double y, double width, double height) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+        }
+
+        @Override
+        public void setRect(Rectangle2D r) {
+            this.x = (float)r.getX();
+            this.y = (float)r.getY();
+            this.width = (float)r.getWidth();
+            this.height = (float)r.getHeight();
+        }
+
+        @Override
+        public int outcode(double px, double py) {
+            int code = 0;
+
+            if (width <= 0.0f) {
+                code |= OUT_LEFT | OUT_RIGHT;
+            } else
+                if (px < x) {
+                    code |= OUT_LEFT;
+                } else
+                    if (px > x + width) {
+                        code |= OUT_RIGHT;
+                    }
+
+            if (height <= 0.0f) {
+                code |= OUT_TOP | OUT_BOTTOM;
+            } else
+                if (py < y) {
+                    code |= OUT_TOP;
+                } else
+                    if (py > y + height) {
+                        code |= OUT_BOTTOM;
+                    }
+
+            return code;
+        }
+
+        @Override
+        public Rectangle2D getBounds2D() {
+            return new Float(x, y, width, height);
+        }
+
+        @Override
+        public Rectangle2D createIntersection(Rectangle2D r) {
+            Rectangle2D dst;
+            if (r instanceof Double) {
+                dst = new Rectangle2D.Double();
+            } else {
+                dst = new Rectangle2D.Float();
+            }
+            Rectangle2D.intersect(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public Rectangle2D createUnion(Rectangle2D r) {
+            Rectangle2D dst;
+            if (r instanceof Double) {
+                dst = new Rectangle2D.Double();
+            } else {
+                dst = new Rectangle2D.Float();
+            }
+            Rectangle2D.union(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public String toString() {
+            // The output format based on 1.5 release behaviour. It could be obtained in the following way
+            // System.out.println(new Rectangle2D.Float().toString())
+            return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of Rectangle2D that represents a 
+     * rectangle whose data values are given as doubles (with double-precision-level
+     * precision).
+     */
+    public static class Double extends Rectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public double x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public double y;
+        
+        /** The width of the rectangle. */
+        public double width;
+        
+        /** The height of the rectangle. */
+        public double height;
+
+        /**
+         * Instantiates a new empty rectangle with double-precision data fields.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new rectangle with the given double values.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         */
+        public Double(double x, double y, double width, double height) {
+            setRect(x, y, width, height);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setRect(double x, double y, double width, double height) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+        }
+
+        @Override
+        public void setRect(Rectangle2D r) {
+            this.x = r.getX();
+            this.y = r.getY();
+            this.width = r.getWidth();
+            this.height = r.getHeight();
+        }
+
+        @Override
+        public int outcode(double px, double py) {
+            int code = 0;
+
+            if (width <= 0.0) {
+                code |= OUT_LEFT | OUT_RIGHT;
+            } else
+                if (px < x) {
+                    code |= OUT_LEFT;
+                } else
+                    if (px > x + width) {
+                        code |= OUT_RIGHT;
+                    }
+
+            if (height <= 0.0) {
+                code |= OUT_TOP | OUT_BOTTOM;
+            } else
+                if (py < y) {
+                    code |= OUT_TOP;
+                } else
+                    if (py > y + height) {
+                        code |= OUT_BOTTOM;
+                    }
+
+            return code;
+        }
+
+        @Override
+        public Rectangle2D getBounds2D() {
+            return new Double(x, y, width, height);
+        }
+
+        @Override
+        public Rectangle2D createIntersection(Rectangle2D r) {
+            Rectangle2D dst = new Rectangle2D.Double();
+            Rectangle2D.intersect(this, r, dst);
+            return dst;
+        }
+
+        @Override
+        public Rectangle2D createUnion(Rectangle2D r) {
+            Rectangle2D dest = new Rectangle2D.Double();
+            Rectangle2D.union(this, r, dest);
+            return dest;
+        }
+
+        @Override
+        public String toString() {
+            // The output format based on 1.5 release behaviour. It could be obtained in the following way
+            // System.out.println(new Rectangle2D.Double().toString())
+            return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+    }
+
+    /**
+     * The Class Iterator provides 
+     * access to the coordinates of the Rectangle2D's boundary modified 
+     * by an AffineTransform. 
+     */
+    class Iterator implements PathIterator {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        double x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        double y;
+        
+        
+        /** The width of the rectangle. */
+        double width;
+        
+        /** The height of the rectangle. */
+        double height;
+                
+        /** The AffineTransform that is used to modify the coordinates 
+         * that are returned by the path iterator. */
+        AffineTransform t;
+        
+        /** The current segment index. */
+        int index;
+        
+        /**
+         * Constructs a new Rectangle2D.Iterator for given rectangle and transformation.
+         * 
+         * @param r - the source Rectangle2D object
+         * @param at - the AffineTransform object to apply to the coordinates 
+         * before returning them
+         */
+        Iterator(Rectangle2D r, AffineTransform at) {
+            this.x = r.getX();
+            this.y = r.getY();
+            this.width = r.getWidth();
+            this.height = r.getHeight();
+            this.t = at;
+            if (width < 0.0 || height < 0.0) {
+                index = 6;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > 5;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            if (index == 0) {
+                type = SEG_MOVETO;
+                coords[0] = x;
+                coords[1] = y;
+            } else {
+                type = SEG_LINETO;
+                switch(index) {
+                case 1:
+                    coords[0] = x + width;
+                    coords[1] = y;
+                    break;
+                case 2:
+                    coords[0] = x + width;
+                    coords[1] = y + height;
+                    break;
+                case 3:
+                    coords[0] = x;
+                    coords[1] = y + height;
+                    break;
+                case 4:
+                    coords[0] = x;
+                    coords[1] = y;
+                    break;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == 5) {
+                return SEG_CLOSE;
+            }
+            int type;
+            if (index == 0) {
+                coords[0] = (float)x;
+                coords[1] = (float)y;
+                type = SEG_MOVETO;
+            } else {
+                type = SEG_LINETO;
+                switch(index) {
+                case 1:
+                    coords[0] = (float)(x + width);
+                    coords[1] = (float)y;
+                    break;
+                case 2:
+                    coords[0] = (float)(x + width);
+                    coords[1] = (float)(y + height);
+                    break;
+                case 3:
+                    coords[0] = (float)x;
+                    coords[1] = (float)(y + height);
+                    break;
+                case 4:
+                    coords[0] = (float)x;
+                    coords[1] = (float)y;
+                    break;
+                }
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Instantiates a new rectangle2 d.
+     */
+    protected Rectangle2D() {
+    }
+
+    /**
+     * Sets the rectangle's location and dimension.
+     * 
+     * @param x the x coordinate of the rectangle's upper left corner
+     * @param y the y coordinate of the rectangle's upper left corner
+     * @param width the width of the rectangle
+     * @param height the height of the rectangle
+     */
+    public abstract void setRect(double x, double y, double width, double height);
+
+    /**
+     * Gets the location of the point with respect to the rectangle and 
+     * packs the information into a single int using the bitmasks 
+     * {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT}, 
+     * {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}.
+     * If the rectangle has zero or negative width, then every point
+     * is regarded as being both to the left and to the right of the
+     * rectangle. Similarly, if the height is zero or negative then 
+     * all points are considered to be both both above and below it.
+     * 
+     * @param x the x coordinate of the point to check
+     * @param y the y coordinate of the point to check
+     * 
+     * @return the point's location with respect to the rectangle.
+     */
+    public abstract int outcode(double x, double y);
+
+    /**
+     * Creates an new rectangle that is the intersection of this rectangle
+     * with the given rectangle. The resulting rectangle may be empty. 
+     * The data of this rectangle is left unchanged.
+     * 
+     * @param r the rectangle to intersect with this rectangle.
+     * 
+     * @return the new rectangle given by intersection.
+     */
+    public abstract Rectangle2D createIntersection(Rectangle2D r);
+
+    /**
+     * Creates an new rectangle that is the union of this rectangle
+     * with the given rectangle. The new rectangle is the smallest 
+     * rectangle which contains both this rectangle and the rectangle
+     * specified as a parameter. The data of this rectangle is left unchanged.
+     * 
+     * @param r the rectangle to combine with this rectangle
+     * 
+     * @return the new rectangle given by union
+     */
+    public abstract Rectangle2D createUnion(Rectangle2D r);
+
+    /**
+     * Sets the data of this rectangle to match the data of the given 
+     * rectangle.
+     * 
+     * @param r the rectangle whose data is to be copied into this rectangle's fields.
+     */
+    public void setRect(Rectangle2D r) {
+        setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setRect(x, y, width, height);
+    }
+
+    public Rectangle2D getBounds2D() {
+        return (Rectangle2D)clone();
+    }
+
+    /**
+     * Determines whether any part of the line segment  between (and including) 
+     * the two given points touches any 
+     * part of the rectangle, including its boundary.
+     * 
+     * @param x1 the x coordinate of one of the points that determines the 
+     * line segment to test
+     * @param y1 the y coordinate of one of the points that determines the 
+     * line segment to test
+     * @param x2 the x coordinate of one of the points that determines the 
+     * line segment to test
+     * @param y2 the y coordinate of one of the points that determines the 
+     * line segment to test
+     * 
+     * @return true, if at least one point of the line segment between the 
+     * two points matches any point of the interior of the rectangle or the
+     * rectangle's boundary.
+     */
+    public boolean intersectsLine(double x1, double y1, double x2, double y2) {
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+        return
+            (rx1 <= x1 && x1 <= rx2 && ry1 <= y1 && y1 <= ry2) ||
+            (rx1 <= x2 && x2 <= rx2 && ry1 <= y2 && y2 <= ry2) ||
+            Line2D.linesIntersect(rx1, ry1, rx2, ry2, x1, y1, x2, y2) ||
+            Line2D.linesIntersect(rx2, ry1, rx1, ry2, x1, y1, x2, y2);
+    }
+
+    /**
+     * Determines whether any part of the specified line segment touches any 
+     * part of the rectangle, including its boundary.
+     * 
+     * @param l the line segment to test
+     * 
+     * @return true, if at least one point of the given line segment 
+     * matches any point of the interior of the rectangle or the
+     * rectangle's boundary.
+     */
+    public boolean intersectsLine(Line2D l) {
+        return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
+    }
+
+    /**
+     * Gets the location of the point with respect to the rectangle and 
+     * packs the information into a single int using the bitmasks 
+     * {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT}, 
+     * {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}.
+     * If the rectangle has zero or negative width, then every point
+     * is regarded as being both to the left and to the right of the
+     * rectangle. Similarly, if the height is zero or negative then 
+     * all points are considered to be both both above and below it.
+     * 
+     * @param p the point to check
+     * 
+     * @return the point's location with respect to the rectangle.
+     */
+    public int outcode(Point2D p) {
+        return outcode(p.getX(), p.getY());
+    }
+
+    public boolean contains(double x, double y) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return
+            x1 <= x && x < x2 &&
+            y1 <= y && y < y2;
+    }
+
+    public boolean intersects(double x, double y, double width, double height) {
+        if (isEmpty() || width <= 0.0 || height <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return
+            x + width > x1 && x < x2 &&
+            y + height > y1 && y < y2;
+    }
+
+    public boolean contains(double x, double y, double width, double height) {
+        if (isEmpty() || width <= 0.0 || height <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        return
+            x1 <= x && x + width <= x2 &&
+            y1 <= y && y + height <= y2;
+    }
+
+    /**
+     * Changes the data values of the destination rectangle to match 
+     * the intersection of the two source rectangles, leaving the 
+     * two source rectangles unchanged. The resulting rectangle may be empty. 
+     * 
+     * @param src1 one of the two source rectangles giving the data to intersect
+     * @param src2 one of the two source rectangles giving the data to intersect
+     * @param dst the destination object where the data of the intersection is written
+     */
+    public static void intersect(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
+        double x1 = Math.max(src1.getMinX(), src2.getMinX());
+        double y1 = Math.max(src1.getMinY(), src2.getMinY());
+        double x2 = Math.min(src1.getMaxX(), src2.getMaxX());
+        double y2 = Math.min(src1.getMaxY(), src2.getMaxY());
+        dst.setFrame(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Changes the data values of the destination rectangle to match 
+     * the union of the two source rectangles, leaving the 
+     * two source rectangles unchanged. The union is the smallest rectangle
+     * tha completely covers the two source rectangles. 
+     * 
+     * @param src1 one of the two source rectangles giving the data
+     * @param src2 one of the two source rectangles giving the data
+     * @param dst the destination object where the data of the union is written
+     */
+    public static void union(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
+        double x1 = Math.min(src1.getMinX(), src2.getMinX());
+        double y1 = Math.min(src1.getMinY(), src2.getMinY());
+        double x2 = Math.max(src1.getMaxX(), src2.getMaxX());
+        double y2 = Math.max(src1.getMaxY(), src2.getMaxY());
+        dst.setFrame(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle so that it includes the given point.
+     * 
+     * @param x the x coordinate of the new point to be covered by the rectangle
+     * @param y the y coordinate of the new point to be covered by the rectangle
+     */
+    public void add(double x, double y) {
+        double x1 = Math.min(getMinX(), x);
+        double y1 = Math.min(getMinY(), y);
+        double x2 = Math.max(getMaxX(), x);
+        double y2 = Math.max(getMaxY(), y);
+        setRect(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    /**
+     * Enlarges the rectangle so that it includes the given point.
+     * 
+     * @param p the new point to be covered by the rectangle
+     */
+    public void add(Point2D p) {
+        add(p.getX(), p.getY());
+    }
+
+    /**
+     * Enlarges the rectangle so that it covers the given rectangle.
+     * 
+     * @param r the new rectangle to be covered by this rectangle
+     */
+    public void add(Rectangle2D r) {
+        union(this, r, this);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    @Override
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new Iterator(this, t);
+    }
+
+    @Override
+    public int hashCode() {
+        HashCode hash = new HashCode();
+        hash.append(getX());
+        hash.append(getY());
+        hash.append(getWidth());
+        hash.append(getHeight());
+        return hash.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Rectangle2D) {
+            Rectangle2D r = (Rectangle2D)obj;
+            return
+                getX() == r.getX() &&
+                getY() == r.getY() &&
+                getWidth() == r.getWidth() &&
+                getHeight() == r.getHeight();
+        }
+        return false;
+    }
+
+}
+
diff --git a/awt/java/awt/geom/RectangularShape.java b/awt/java/awt/geom/RectangularShape.java
new file mode 100644
index 0000000..0a77dfd
--- /dev/null
+++ b/awt/java/awt/geom/RectangularShape.java
@@ -0,0 +1,276 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+
+/**
+ * The Class RectangularShape represents a Shape whose data is 
+ * (at least partially) described by a rectangular frame. This includes 
+ * shapes which are obviously rectangular (such as Rectangle2D) as well as
+ * shapes like Arc2D which are largely determined by the rectangle they 
+ * fit inside.
+ */
+public abstract class RectangularShape implements Shape, Cloneable {
+
+    /**
+     * Instantiates a new rectangular shape.
+     */
+    protected RectangularShape() {
+    }
+
+    /**
+     * Gets the x coordinate of the upper left corner of the rectangle.
+     * 
+     * @return the x coordinate of the upper left corner of the rectangle.
+     */
+    public abstract double getX();
+
+    /**
+     * Gets the y coordinate of the upper left corner of the rectangle.
+     * 
+     * @return the y coordinate of the upper left corner of the rectangle.
+     */
+    public abstract double getY();
+
+    /**
+     * Gets the width of the rectangle.
+     * 
+     * @return the width of the rectangle.
+     */
+    public abstract double getWidth();
+
+    /**
+     * Gets the height of the rectangle.
+     * 
+     * @return the height of the rectangle.
+     */
+    public abstract double getHeight();
+
+    /**
+     * Checks if this is an empty rectangle: one with zero as its width or height.
+     * 
+     * @return true, if the width or height is empty.
+     */
+    public abstract boolean isEmpty();
+
+    /**
+     * Sets the data for the bounding rectangle in terms of double values. 
+     * 
+     * @param x the x coordinate of the upper left corner of the rectangle.
+     * @param y the y coordinate of the upper left corner of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     */
+    public abstract void setFrame(double x, double y, double w, double h);
+
+    /**
+     * Gets the minimum x value of the bounding rectangle (the x 
+     * coordinate of the upper left corner of the rectangle).
+     * 
+     * @return the minimum x value of the bounding rectangle.
+     */
+    public double getMinX() {
+        return getX();
+    }
+
+    /**
+     * Gets the minimum y value of the bounding rectangle (the y 
+     * coordinate of the upper left corner of the rectangle).
+     * 
+     * @return the minimum y value of the bounding rectangle.
+     */
+    public double getMinY() {
+        return getY();
+    }
+
+    /**
+     * Gets the maximum x value of the bounding rectangle (the x
+     * coordinate of the upper left corner of the rectangle plus the 
+     * rectangle's width).
+     * 
+     * @return the maximum x value of the bounding rectangle.
+     */
+    public double getMaxX() {
+        return getX() + getWidth();
+    }
+
+    /**
+     * Gets the maximum y value of the bounding rectangle (the y
+     * coordinate of the upper left corner of the rectangle plus the 
+     * rectangle's height).
+     * 
+     * @return the maximum y value of the bounding rectangle.
+     */
+    public double getMaxY() {
+        return getY() + getHeight();
+    }
+
+    /**
+     * Gets the x coordinate of the center of the rectangle.
+     * 
+     * @return the x coordinate of the center of the rectangle.
+     */
+    public double getCenterX() {
+        return getX() + getWidth() / 2.0;
+    }
+
+    /**
+     * Gets the y coordinate of the center of the rectangle.
+     * 
+     * @return the y coordinate of the center of the rectangle.
+     */
+    public double getCenterY() {
+        return getY() + getHeight() / 2.0;
+    }
+
+    /**
+     * Places the rectangle's size and location data in a new Rectangle2D
+     * object and returns it.
+     * 
+     * @return the bounding rectangle as a new Rectangle2D object.
+     */
+    public Rectangle2D getFrame() {
+        return new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
+    }
+
+    /**
+     * Sets the bounding rectangle in terms of a Point2D which gives its
+     * upper left corner and a Dimension2D object giving its width and height.
+     * 
+     * @param loc the new upper left corner coordinate.
+     * @param size the new size dimensions.
+     */
+    public void setFrame(Point2D loc, Dimension2D size) {
+        setFrame(loc.getX(), loc.getY(), size.getWidth(), size.getHeight());
+    }
+
+    /**
+     * Sets the bounding rectangle to match the data contained in the 
+     * specified Rectangle2D.
+     * 
+     * @param r the rectangle that gives the new frame data.
+     */
+    public void setFrame(Rectangle2D r) {
+        setFrame(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+    }
+
+    /**
+     * Sets the framing rectangle given two opposite corners. Any two corners
+     * may be used in any order as long as they are diagonally opposite one another.
+     * 
+     * @param x1 the x coordinate of one of the corner points.
+     * @param y1 the y coordinate of one of the corner points.
+     * @param x2 the x coordinate of the other corner point.
+     * @param y2 the y coordinate of the other corner point.
+     */
+    public void setFrameFromDiagonal(double x1, double y1, double x2, double y2) {
+        double rx, ry, rw, rh;
+        if (x1 < x2) {
+            rx = x1;
+            rw = x2 - x1;
+        } else {
+            rx = x2;
+            rw = x1 - x2;
+        }
+        if (y1 < y2) {
+            ry = y1;
+            rh = y2 - y1;
+        } else {
+            ry = y2;
+            rh = y1 - y2;
+        }
+        setFrame(rx, ry, rw, rh);
+    }
+
+    /**
+     * Sets the framing rectangle given two opposite corners. Any two corners
+     * may be used in any order as long as they are diagonally opposite one another.
+     * 
+     * @param p1 one of the corner points.
+     * @param p2 the other corner point.
+     */
+    public void setFrameFromDiagonal(Point2D p1, Point2D p2) {
+        setFrameFromDiagonal(p1.getX(), p1.getY(), p2.getX(), p2.getY());
+    }
+
+    /**
+     * Sets the framing rectangle given the center point and one corner. Any
+     * corner may be used.
+     * 
+     * @param centerX the x coordinate of the center point.
+     * @param centerY the y coordinate of the center point.
+     * @param cornerX the x coordinate of one of the corner points.
+     * @param cornerY the y coordinate of one of the corner points.
+     */
+    public void setFrameFromCenter(double centerX, double centerY, double cornerX, double cornerY) {
+        double width = Math.abs(cornerX - centerX);
+        double height = Math.abs(cornerY - centerY);
+        setFrame(centerX - width, centerY - height, width * 2.0, height * 2.0);
+    }
+
+    /**
+     * Sets the framing rectangle given the center point and one corner. Any
+     * corner may be used.
+     * 
+     * @param center the center point.
+     * @param corner a corner point.
+     */
+    public void setFrameFromCenter(Point2D center, Point2D corner) {
+        setFrameFromCenter(center.getX(), center.getY(), corner.getX(), corner.getY());
+    }
+
+    public boolean contains(Point2D point) {
+        return contains(point.getX(), point.getY());
+    }
+
+    public boolean intersects(Rectangle2D rect) {
+        return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public boolean contains(Rectangle2D rect) {
+        return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
+    }
+
+    public Rectangle getBounds() {
+        int x1 = (int)Math.floor(getMinX());
+        int y1 = (int)Math.floor(getMinY());
+        int x2 = (int)Math.ceil(getMaxX());
+        int y2 = (int)Math.ceil(getMaxY());
+        return new Rectangle(x1, y1, x2 - x1, y2 - y1);
+    }
+
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new FlatteningPathIterator(getPathIterator(t), flatness);
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/geom/RoundRectangle2D.java b/awt/java/awt/geom/RoundRectangle2D.java
new file mode 100644
index 0000000..680a146
--- /dev/null
+++ b/awt/java/awt/geom/RoundRectangle2D.java
@@ -0,0 +1,552 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package java.awt.geom;
+
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RoundRectangle2D describes a rectangle with rounded 
+ * corners with high-precision data that is appropriate for geometric
+ * operations.
+ */
+public abstract class RoundRectangle2D extends RectangularShape {
+
+    /**
+     * The Class Float is the subclass of RoundRectangle2D that has all 
+     * of its data values stored with float-level precision.
+     */
+    public static class Float extends RoundRectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public float x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public float y;
+        
+        /** The width of the rectangle. */
+        public float width;
+        
+        /** The height of the rectangle. */
+        public float height;
+        
+        /** The arcwidth of the rounded corners. */
+        public float arcwidth;
+        
+        /** The archeight of the rounded corners. */
+        public float archeight;
+
+        /**
+         * Instantiates a new float-valued RoundRectangle2D with 
+         * its data-values set to zero.
+         */
+        public Float() {
+        }
+
+        /**
+         * Instantiates a new float-valued RoundRectangle2D with 
+         * the specified data values
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         * @param arcwidth the arcwidth of the rounded corners
+         * @param archeight the archeight of the rounded corners
+         */
+        public Float(float x, float y, float width, float height, float arcwidth, float archeight) {
+            setRoundRect(x, y, width, height, arcwidth, archeight);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getArcWidth() {
+            return arcwidth;
+        }
+
+        @Override
+        public double getArcHeight() {
+            return archeight;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0f || height <= 0.0f;
+        }
+
+        /**
+         * Sets the data of the round rect.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         * @param arcwidth the arcwidth of the rounded corners
+         * @param archeight the archeight of the rounded corners
+         */
+        public void setRoundRect(float x, float y, float width, float height, float arcwidth, float archeight) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.arcwidth = arcwidth;
+            this.archeight = archeight;
+        }
+
+        @Override
+        public void setRoundRect(double x, double y, double width, double height, double arcwidth, double archeight) {
+            this.x = (float)x;
+            this.y = (float)y;
+            this.width = (float)width;
+            this.height = (float)height;
+            this.arcwidth = (float)arcwidth;
+            this.archeight = (float)archeight;
+        }
+
+        @Override
+        public void setRoundRect(RoundRectangle2D rr) {
+            this.x = (float)rr.getX();
+            this.y = (float)rr.getY();
+            this.width = (float)rr.getWidth();
+            this.height = (float)rr.getHeight();
+            this.arcwidth = (float)rr.getArcWidth();
+            this.archeight = (float)rr.getArcHeight();
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Float(x, y, width, height);
+        }
+    }
+
+    /**
+     * The Class Double is the subclass of RoundRectangle2D that has all 
+     * of its data values stored with double-level precision.
+     */
+    public static class Double extends RoundRectangle2D {
+
+        /** The x coordinate of the rectangle's upper left corner. */
+        public double x;
+        
+        /** The y coordinate of the rectangle's upper left corner. */
+        public double y;
+        
+        /** The width of the rectangle. */
+        public double width;
+        
+        /** The height of the rectangle. */
+        public double height;
+        
+        /** The arcwidth of the rounded corners. */
+        public double arcwidth;
+        
+        /** The archeight of the rounded corners. */
+        public double archeight;
+
+        /**
+         * Instantiates a new double-valued RoundRectangle2D with 
+         * its data-values set to zero.
+         */
+        public Double() {
+        }
+
+        /**
+         * Instantiates a new double-valued RoundRectangle2D with 
+         * the specified data values.
+         * 
+         * @param x the x coordinate of the rectangle's upper left corner
+         * @param y the y coordinate of the rectangle's upper left corner
+         * @param width the width of the rectangle
+         * @param height the height of the rectangle
+         * @param arcwidth the arcwidth of the rounded corners
+         * @param archeight the archeight of the rounded corners
+         */
+        public Double(double x, double y, double width, double height, double arcwidth, double archeight) {
+            setRoundRect(x, y, width, height, arcwidth, archeight);
+        }
+
+        @Override
+        public double getX() {
+            return x;
+        }
+
+        @Override
+        public double getY() {
+            return y;
+        }
+
+        @Override
+        public double getWidth() {
+            return width;
+        }
+
+        @Override
+        public double getHeight() {
+            return height;
+        }
+
+        @Override
+        public double getArcWidth() {
+            return arcwidth;
+        }
+
+        @Override
+        public double getArcHeight() {
+            return archeight;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return width <= 0.0 || height <= 0.0;
+        }
+
+        @Override
+        public void setRoundRect(double x, double y, double width, double height, double arcwidth, double archeight) {
+            this.x = x;
+            this.y = y;
+            this.width = width;
+            this.height = height;
+            this.arcwidth = arcwidth;
+            this.archeight = archeight;
+        }
+
+        @Override
+        public void setRoundRect(RoundRectangle2D rr) {
+            this.x = rr.getX();
+            this.y = rr.getY();
+            this.width = rr.getWidth();
+            this.height = rr.getHeight();
+            this.arcwidth = rr.getArcWidth();
+            this.archeight = rr.getArcHeight();
+        }
+
+        public Rectangle2D getBounds2D() {
+            return new Rectangle2D.Double(x, y, width, height);
+        }
+    }
+
+    /*
+     * RoundRectangle2D path iterator 
+     */
+    /**
+     * The subclass of PathIterator to traverse a RoundRectangle2D.
+     */
+    class Iterator implements PathIterator {
+
+        /*
+         * Path for round corners generated the same way as Ellipse2D
+         */
+
+        /** The coefficient to calculate control points of Bezier curves. */
+        double u = 0.5 - 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
+
+        /** The points coordinates calculation table. */
+        double points[][] = {
+                { 0.0,  0.5, 0.0,  0.0 }, // MOVETO
+                { 1.0, -0.5, 0.0,  0.0 }, // LINETO
+                { 1.0,   -u, 0.0,  0.0,   // CUBICTO
+                  1.0,  0.0, 0.0,    u,
+                  1.0,  0.0, 0.0,  0.5 },
+                { 1.0,  0.0, 1.0, -0.5 }, // LINETO
+                { 1.0,  0.0, 1.0,   -u,   // CUBICTO
+                  1.0,   -u, 1.0,  0.0,
+                  1.0, -0.5, 1.0,  0.0 },
+                { 0.0,  0.5, 1.0,  0.0 }, // LINETO
+                { 0.0,    u, 1.0,  0.0,   // CUBICTO
+                  0.0,  0.0, 1.0,   -u,
+                  0.0,  0.0, 1.0, -0.5 },
+                { 0.0,  0.0, 0.0,  0.5 }, // LINETO
+                { 0.0,  0.0, 0.0,    u,   // CUBICTO
+                  0.0,    u, 0.0,  0.0,
+                  0.0,  0.5, 0.0,  0.0 } };
+
+        /** The segment types correspond to points array. */
+        int types[] = {
+                SEG_MOVETO,
+                SEG_LINETO,
+                SEG_CUBICTO,
+                SEG_LINETO,
+                SEG_CUBICTO,
+                SEG_LINETO,
+                SEG_CUBICTO,
+                SEG_LINETO,
+                SEG_CUBICTO};
+
+        /** The x coordinate of left-upper corner of the round rectangle bounds. */
+        double x;
+        
+        /** The y coordinate of left-upper corner of the round rectangle bounds. */
+        double y;
+        
+        /** The width of the round rectangle bounds. */
+        double width;
+        
+        /** The height of the round rectangle bounds. */
+        double height;
+        
+        /** The width of arc corners of the round rectangle. */
+        double aw;
+        
+        /** The height of arc corners of the round rectangle. */
+        double ah;
+
+        /** The path iterator transformation. */
+        AffineTransform t;
+
+        /** The current segmenet index. */
+        int index;
+
+        /**
+         * Constructs a new RoundRectangle2D.Iterator for given round rectangle and transformation.
+         * 
+         * @param rr - the source RoundRectangle2D object
+         * @param at - the AffineTransform object to apply rectangle path
+         */
+        Iterator(RoundRectangle2D rr, AffineTransform at) {
+            this.x = rr.getX();
+            this.y = rr.getY();
+            this.width = rr.getWidth();
+            this.height = rr.getHeight();
+            this.aw = Math.min(width, rr.getArcWidth());
+            this.ah = Math.min(height, rr.getArcHeight());
+            this.t = at;
+            if (width < 0.0 || height < 0.0 || aw < 0.0 || ah < 0.0) {
+                index = points.length;
+            }
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return index > points.length;
+        }
+
+        public void next() {
+            index++;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == points.length) {
+                return SEG_CLOSE;
+            }
+            int j = 0;
+            double p[] = points[index];
+            for (int i = 0; i < p.length; i += 4) {
+                coords[j++] = x + p[i + 0] * width + p[i + 1] * aw;
+                coords[j++] = y + p[i + 2] * height + p[i + 3] * ah;
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, j / 2);
+            }
+            return types[index];
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            if (index == points.length) {
+                return SEG_CLOSE;
+            }
+            int j = 0;
+            double p[] = points[index];
+            for (int i = 0; i < p.length; i += 4) {
+                coords[j++] = (float)(x + p[i + 0] * width + p[i + 1] * aw);
+                coords[j++] = (float)(y + p[i + 2] * height + p[i + 3] * ah);
+            }
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, j / 2);
+            }
+            return types[index];
+        }
+
+    }
+
+    /**
+     * Instantiates a new RoundRectangle2D.
+     */
+    protected RoundRectangle2D() {
+    }
+
+    /**
+     * Gets the arc width.
+     * 
+     * @return the arc width
+     */
+    public abstract double getArcWidth();
+
+    /**
+     * Gets the arc height.
+     * 
+     * @return the arc height
+     */
+    public abstract double getArcHeight();
+
+    /**
+     * Sets the data of the RoundRectangle2D.
+     * 
+     * @param x the x coordinate of the rectangle's upper left corner
+     * @param y the y coordinate of the rectangle's upper left corner
+     * @param width the width of the rectangle
+     * @param height the height of the rectangle
+     * @param arcWidth the arcwidth of the rounded corners
+     * @param arcHeight the archeight of the rounded corners
+     */
+    public abstract void setRoundRect(double x, double y, double width, double height,
+            double arcWidth, double arcHeight);
+
+    /**
+     * Sets the data of the RoundRectangle2D by copying the values
+     * from an existing RoundRectangle2D.
+     * 
+     * @param rr the round rectangle to copy the data from
+     * 
+     * @throws NullPointerException if rr is null
+     */
+    public void setRoundRect(RoundRectangle2D rr) {
+        setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(), rr
+                .getArcWidth(), rr.getArcHeight());
+    }
+
+    @Override
+    public void setFrame(double x, double y, double width, double height) {
+        setRoundRect(x, y, width, height, getArcWidth(), getArcHeight());
+    }
+
+    public boolean contains(double px, double py) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double rx1 = getX();
+        double ry1 = getY();
+        double rx2 = rx1 + getWidth();
+        double ry2 = ry1 + getHeight();
+
+        if (px < rx1 || px >= rx2 || py < ry1 || py >= ry2) {
+            return false;
+        }
+
+        double aw = getArcWidth() / 2.0;
+        double ah = getArcHeight() / 2.0;
+
+        double cx, cy;
+
+        if (px < rx1 + aw) {
+            cx = rx1 + aw;
+        } else
+            if (px > rx2 - aw) {
+                cx = rx2 - aw;
+            } else {
+                return true;
+            }
+
+        if (py < ry1 + ah) {
+            cy = ry1 + ah;
+        } else
+            if (py > ry2 - ah) {
+                cy = ry2 - ah;
+            } else {
+                return true;
+            }
+
+        px = (px - cx) / aw;
+        py = (py - cy) / ah;
+        return px * px + py * py <= 1.0;
+    }
+
+    public boolean intersects(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double x1 = getX();
+        double y1 = getY();
+        double x2 = x1 + getWidth();
+        double y2 = y1 + getHeight();
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        if (rx2 < x1 || x2 < rx1 || ry2 < y1 || y2 < ry1) {
+            return false;
+        }
+
+        double cx = (x1 + x2) / 2.0;
+        double cy = (y1 + y2) / 2.0;
+
+        double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
+        double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
+
+        return contains(nx, ny);
+    }
+
+    public boolean contains(double rx, double ry, double rw, double rh) {
+        if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
+            return false;
+        }
+
+        double rx1 = rx;
+        double ry1 = ry;
+        double rx2 = rx + rw;
+        double ry2 = ry + rh;
+
+        return
+            contains(rx1, ry1) &&
+            contains(rx2, ry1) &&
+            contains(rx2, ry2) &&
+            contains(rx1, ry2);
+    }
+
+    public PathIterator getPathIterator(AffineTransform at) {
+        return new Iterator(this, at);
+    }
+
+}
+
diff --git a/awt/java/awt/im/InputContext.java b/awt/java/awt/im/InputContext.java
new file mode 100644
index 0000000..3468474
--- /dev/null
+++ b/awt/java/awt/im/InputContext.java
@@ -0,0 +1,77 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.awt.AWTEvent;
+//???AWT: import java.awt.Component;
+import java.util.Locale;
+
+import org.apache.harmony.awt.im.InputMethodContext;
+
+public class InputContext {
+    protected InputContext() {
+    }
+
+    public static InputContext getInstance() {
+        return new InputMethodContext();
+    }
+
+    public void dispatchEvent(AWTEvent event) {
+    }
+
+    public void dispose() {
+    }
+
+    public void endComposition() {
+    }
+
+    public Object getInputMethodControlObject() {
+        return null;
+    }
+
+    public Locale getLocale() {
+        return null;
+    }
+
+    public boolean isCompositionEnabled() {
+        return false;
+    }
+
+    public void reconvert() {
+    }
+
+    //???AWT
+    /*
+    public void removeNotify(Component client) {
+    }
+    */
+
+    public boolean selectInputMethod(Locale locale) {
+        return false;
+    }
+
+    public void setCharacterSubsets(Character.Subset[] subsets) {
+    }
+    
+    public void setCompositionEnabled(boolean enable) {
+    }
+}
+
diff --git a/awt/java/awt/im/InputMethodHighlight.java b/awt/java/awt/im/InputMethodHighlight.java
new file mode 100644
index 0000000..53bb20b
--- /dev/null
+++ b/awt/java/awt/im/InputMethodHighlight.java
@@ -0,0 +1,89 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.util.Map;
+import java.awt.font.TextAttribute;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class InputMethodHighlight {
+
+    public static final int RAW_TEXT = 0;
+
+    public static final int CONVERTED_TEXT = 1;
+
+    public static final InputMethodHighlight
+        UNSELECTED_RAW_TEXT_HIGHLIGHT = new InputMethodHighlight(false, RAW_TEXT);
+
+    public static final InputMethodHighlight
+        SELECTED_RAW_TEXT_HIGHLIGHT = new InputMethodHighlight(true, RAW_TEXT);
+
+    public static final InputMethodHighlight
+        UNSELECTED_CONVERTED_TEXT_HIGHLIGHT = 
+            new InputMethodHighlight(false, CONVERTED_TEXT);
+
+    public static final InputMethodHighlight
+        SELECTED_CONVERTED_TEXT_HIGHLIGHT = 
+            new InputMethodHighlight(true, CONVERTED_TEXT);
+    
+    private boolean selected;
+    private int state;
+    private int variation;
+    private Map<TextAttribute,?> style;
+
+    public InputMethodHighlight(boolean selected, int state, int variation) {
+        this(selected, state, variation, null);
+    }
+
+    public InputMethodHighlight(boolean selected, int state,
+                                int variation, Map<java.awt.font.TextAttribute, ?> style) {
+        if ((state != RAW_TEXT) && (state != CONVERTED_TEXT)) {
+            // awt.20B=unknown input method highlight state
+            throw new IllegalArgumentException(Messages.getString("awt.20B")); //$NON-NLS-1$
+        }
+        this.selected = selected;
+        this.state = state;
+        this.variation = variation;
+        this.style = style;
+    }
+
+    public InputMethodHighlight(boolean selected, int state) {
+        this(selected, state, 0, null);
+    }
+
+    public int getState() {
+        return state;
+    }
+
+    public Map<java.awt.font.TextAttribute, ?> getStyle() {
+        return style;
+    }
+
+    public int getVariation() {
+        return variation;
+    }
+
+    public boolean isSelected() {
+        return selected;
+    }
+}
+
diff --git a/awt/java/awt/im/InputMethodRequests.java b/awt/java/awt/im/InputMethodRequests.java
new file mode 100644
index 0000000..bdd25e6
--- /dev/null
+++ b/awt/java/awt/im/InputMethodRequests.java
@@ -0,0 +1,43 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im;
+
+import java.awt.Rectangle;
+import java.awt.font.TextHitInfo;
+import java.text.AttributedCharacterIterator;
+
+public interface InputMethodRequests {
+
+    public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes);
+
+    public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, AttributedCharacterIterator.Attribute[] attributes);
+
+    public int getCommittedTextLength();
+
+    public int getInsertPositionOffset();
+
+    public TextHitInfo getLocationOffset(int x, int y);
+
+    public AttributedCharacterIterator getSelectedText(AttributedCharacterIterator.Attribute[] attributes);
+
+    public Rectangle getTextLocation(TextHitInfo offset);
+}
+
diff --git a/awt/java/awt/im/InputSubset.java b/awt/java/awt/im/InputSubset.java
new file mode 100644
index 0000000..02a1049
--- /dev/null
+++ b/awt/java/awt/im/InputSubset.java
@@ -0,0 +1,53 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package java.awt.im;
+
+public final class InputSubset extends Character.Subset {
+
+    public static final InputSubset LATIN = new InputSubset("LATIN"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        LATIN_DIGITS = new InputSubset("LATIN_DIGITS"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        TRADITIONAL_HANZI = new InputSubset("TRADITIONAL_HANZI"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        SIMPLIFIED_HANZI = new InputSubset("SIMPLIFIED_HANZI"); //$NON-NLS-1$
+
+    public static final InputSubset KANJI = new InputSubset("KANJI"); //$NON-NLS-1$
+
+    public static final InputSubset HANJA = new InputSubset("HANJA"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        HALFWIDTH_KATAKANA = new InputSubset("HALFWIDTH_KATAKANA"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        FULLWIDTH_LATIN = new InputSubset("FULLWIDTH_LATIN"); //$NON-NLS-1$
+
+    public static final InputSubset 
+        FULLWIDTH_DIGITS = new InputSubset("FULLWIDTH_DIGITS"); //$NON-NLS-1$
+
+    private InputSubset(String name) {
+        super(name);
+    }
+}
+
diff --git a/awt/java/awt/im/spi/InputMethod.java b/awt/java/awt/im/spi/InputMethod.java
new file mode 100644
index 0000000..2c98c46
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethod.java
@@ -0,0 +1,61 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im.spi;
+
+import java.awt.AWTEvent;
+import java.awt.Rectangle;
+import java.util.Locale;
+
+public interface InputMethod {
+
+    public void activate();
+
+    public void deactivate(boolean isTemporary);
+
+    public void dispatchEvent(AWTEvent event);
+
+    public void dispose();
+
+    public void endComposition();
+
+    public Object getControlObject();
+
+    public Locale getLocale();
+
+    public void hideWindows();
+
+    public boolean isCompositionEnabled();
+
+    public void notifyClientWindowChange(Rectangle bounds);
+
+    public void reconvert();
+
+    public void removeNotify();
+
+    public void setCharacterSubsets(Character.Subset[] subsets);
+
+    public void setCompositionEnabled(boolean enable);
+
+    public void setInputMethodContext(InputMethodContext context);
+
+    public boolean setLocale(Locale locale);
+}
+
diff --git a/awt/java/awt/im/spi/InputMethodContext.java b/awt/java/awt/im/spi/InputMethodContext.java
new file mode 100644
index 0000000..ca33e87
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethodContext.java
@@ -0,0 +1,40 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im.spi;
+
+//???AWT: import java.awt.Window;
+import java.awt.font.TextHitInfo;
+import java.awt.im.InputMethodRequests;
+import java.text.AttributedCharacterIterator;
+//???AWT: import javax.swing.JFrame;
+
+public interface InputMethodContext extends InputMethodRequests {
+
+//    ???AWT: public JFrame createInputMethodJFrame(String title, boolean attachToInputContext);
+
+//    ???AWT: public Window createInputMethodWindow(String title, boolean attachToInputContext);
+
+    public void dispatchInputMethodEvent(int id, AttributedCharacterIterator text, int committedCharacterCount, TextHitInfo caret, TextHitInfo visiblePosition);
+
+    public void enableClientWindowNotification(InputMethod inputMethod, boolean enable);
+
+}
+
diff --git a/awt/java/awt/im/spi/InputMethodDescriptor.java b/awt/java/awt/im/spi/InputMethodDescriptor.java
new file mode 100644
index 0000000..3068cac
--- /dev/null
+++ b/awt/java/awt/im/spi/InputMethodDescriptor.java
@@ -0,0 +1,40 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.im.spi;
+
+import java.awt.AWTException;
+import java.awt.Image;
+import java.util.Locale;
+
+public interface InputMethodDescriptor {
+
+    public Locale[] getAvailableLocales() throws AWTException;
+
+    public InputMethod createInputMethod() throws Exception;
+
+    public String getInputMethodDisplayName(Locale inputLocale, Locale displayLanguage);
+
+    public Image getInputMethodIcon(Locale inputLocale);
+
+    public boolean hasDynamicLocaleList();
+
+}
+
diff --git a/awt/java/awt/image/AffineTransformOp.java b/awt/java/awt/image/AffineTransformOp.java
new file mode 100644
index 0000000..546837a
--- /dev/null
+++ b/awt/java/awt/image/AffineTransformOp.java
@@ -0,0 +1,617 @@
+/*
+ *  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 Oleg V. Khaschansky, Denis M. Kishenko
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.*;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The AffineTransform class translates coordinates from 2D coordinates 
+ * in the source image or Raster to 2D coordinates in the destination 
+ * image or Raster using Affine transformation. The number of bands in 
+ * the source Raster should equal to the number of bands in the destination
+ * Raster.
+ */
+public class AffineTransformOp implements BufferedImageOp, RasterOp {
+    
+    /** 
+     * The Constant TYPE_NEAREST_NEIGHBOR indicates nearest-neighbor 
+     * interpolation type. 
+     */
+    public static final int TYPE_NEAREST_NEIGHBOR = 1;
+    
+    /** 
+     * The Constant TYPE_BILINEAR indicates bilinear interpolation type. 
+     */
+    public static final int TYPE_BILINEAR = 2;
+    
+    /** The Constant TYPE_BICUBIC indicates bicubic interpolation type. */
+    public static final int TYPE_BICUBIC = 3;
+
+    /** The i type. */
+    private int iType; // interpolation type
+    
+    /** The at. */
+    private AffineTransform at;
+    
+    /** The hints. */
+    private RenderingHints hints;
+
+    static {
+        // TODO - uncomment
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new AffineTransformOp with the specified
+     * AffineTransform and RenderingHints object which defines 
+     * the interpolation type.
+     * 
+     * @param xform the AffineTransform.
+     * @param hints the RenderingHints object which defines 
+     * the interpolation type.
+     */
+    public AffineTransformOp(AffineTransform xform, RenderingHints hints) {
+        this(xform, TYPE_NEAREST_NEIGHBOR);
+        this.hints = hints;
+
+        if (hints != null) {
+            Object hint = hints.get(RenderingHints.KEY_INTERPOLATION);
+            if (hint != null) {
+                // Nearest neighbor is default
+                if (hint == RenderingHints.VALUE_INTERPOLATION_BILINEAR) {
+                    this.iType = TYPE_BILINEAR;
+                } else if (hint == RenderingHints.VALUE_INTERPOLATION_BICUBIC) {
+                    this.iType = TYPE_BICUBIC;
+                }
+            } else {
+                hint = hints.get(RenderingHints.KEY_RENDERING);
+                // Determine from rendering quality
+                if (hint == RenderingHints.VALUE_RENDER_QUALITY) {
+                    this.iType = TYPE_BILINEAR;
+                // For speed use nearest neighbor
+                }
+            }
+        }
+    }
+
+    /**
+     * Instantiates a new AffineTransformOp with the specified
+     * AffineTransform and a specified interpolation type from the 
+     * list of predefined interpolation types.
+     * 
+     * @param xform the AffineTransform.
+     * @param interp the one of predefined interpolation types:
+     * TYPE_NEAREST_NEIGHBOR, TYPE_BILINEAR, or TYPE_BICUBIC.
+     */
+    public AffineTransformOp(AffineTransform xform, int interp) {
+        if (Math.abs(xform.getDeterminant()) <= Double.MIN_VALUE) {
+            // awt.24F=Unable to invert transform {0}
+            throw new ImagingOpException(Messages.getString("awt.24F", xform)); //$NON-NLS-1$
+        }
+
+        this.at = (AffineTransform) xform.clone();
+
+        if (interp != TYPE_NEAREST_NEIGHBOR && interp != TYPE_BILINEAR && interp != TYPE_BICUBIC) {
+            // awt.250=Unknown interpolation type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.250", interp)); //$NON-NLS-1$
+        }
+
+        this.iType = interp;
+    }
+
+    /**
+     * Gets the interpolation type.
+     * 
+     * @return the interpolation type
+     */
+    public final int getInterpolationType() {
+        return iType;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        if (hints == null) {
+            Object value = null;
+
+            switch (iType) {
+                case TYPE_NEAREST_NEIGHBOR:
+                    value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+                    break;
+                case TYPE_BILINEAR:
+                    value = RenderingHints.VALUE_INTERPOLATION_BILINEAR;
+                    break;
+                case TYPE_BICUBIC:
+                    value = RenderingHints.VALUE_INTERPOLATION_BICUBIC;
+                    break;
+                default:
+                    value = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
+            }
+
+            hints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, value);
+        }
+
+        return hints;
+    }
+
+    /**
+     * Gets the affine transform associated with this AffineTransformOp.
+     * 
+     * @return the AffineTransform.
+     */
+    public final AffineTransform getTransform() {
+        return (AffineTransform) at.clone();
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        return at.transform(srcPt, dstPt);
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        // We position source raster to (0,0) even if it is translated child raster.
+        // This means that we need only width and height of the src
+        int width = src.getWidth();
+        int height = src.getHeight();
+
+        float[] corners = {
+            0, 0,
+            width, 0,
+            width, height,
+            0, height
+        };
+
+        at.transform(corners, 0, corners, 0, 4);
+
+        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0);
+        bounds.add(corners[2], corners[3]);
+        bounds.add(corners[4], corners[5]);
+        bounds.add(corners[6], corners[7]);
+
+        return bounds;
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
+        Rectangle2D newBounds = getBounds2D(src);
+
+        // Destination image should include (0,0) + positive part
+        // of the area bounded by newBounds (in source coordinate system).
+        double dstWidth = newBounds.getX() + newBounds.getWidth();
+        double dstHeight = newBounds.getY() + newBounds.getHeight();
+
+        if (dstWidth <= 0 || dstHeight <= 0) {
+            // awt.251=Transformed width ({0}) and height ({1}) should be greater than 0
+            throw new RasterFormatException(
+                    Messages.getString("awt.251", dstWidth, dstHeight)); //$NON-NLS-1$
+        }
+
+        if (destCM != null) {
+            return new BufferedImage(destCM,
+                    destCM.createCompatibleWritableRaster((int)dstWidth, (int)dstHeight),
+                    destCM.isAlphaPremultiplied(),
+                    null
+            );
+        }
+
+        ColorModel cm = src.getColorModel();
+
+        // Interpolation other than NN doesn't make any sense for index color
+        if (iType != TYPE_NEAREST_NEIGHBOR && cm instanceof IndexColorModel) {
+            return new BufferedImage((int)dstWidth, (int)dstHeight, BufferedImage.TYPE_INT_ARGB);
+        }
+
+        // OK, we can get source color model
+        return new BufferedImage(cm,
+                src.getRaster().createCompatibleWritableRaster((int)dstWidth, (int)dstHeight),
+                cm.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public WritableRaster createCompatibleDestRaster (Raster src) {
+        // Here approach is other then in createCompatibleDestImage -
+        // destination should include only
+        // transformed image, but not (0,0) in source coordinate system
+
+        Rectangle2D newBounds = getBounds2D(src);
+        return src.createCompatibleWritableRaster(
+                (int) newBounds.getX(), (int) newBounds.getY(),
+                (int) newBounds.getWidth(), (int)newBounds.getHeight()
+        );
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (src == dst) {
+            // awt.252=Source can't be same as the destination
+            throw new IllegalArgumentException(Messages.getString("awt.252")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        BufferedImage finalDst = null;
+
+        if (
+                srcCM instanceof IndexColorModel &&
+                (iType != TYPE_NEAREST_NEIGHBOR || srcCM.getPixelSize() % 8 != 0)
+        ) {
+            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), true);
+            srcCM = src.getColorModel();
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestImage(src, srcCM);
+        } else {
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB as same
+                if (
+                   !(
+                     (src.getType() == BufferedImage.TYPE_INT_RGB ||
+                      src.getType() == BufferedImage.TYPE_INT_ARGB) &&
+                     (dst.getType() == BufferedImage.TYPE_INT_RGB ||
+                      dst.getType() == BufferedImage.TYPE_INT_ARGB)
+                    )
+                ) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, srcCM);
+                }
+            }
+        }
+
+        // Skip alpha channel for TYPE_INT_RGB images
+        if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+        // TODO - uncomment
+        //if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) != 0)
+            //throw new ImagingOpException ("Unable to transform source");
+        }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (src == dst) {
+            // awt.252=Source can't be same as the destination
+            throw new IllegalArgumentException(Messages.getString("awt.252")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (src.getNumBands() != dst.getNumBands()) {
+            // awt.253=Different number of bands in source and destination
+            throw new IllegalArgumentException(Messages.getString("awt.253")); //$NON-NLS-1$
+        }
+
+        if (slowFilter(src, dst) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException(Messages.getString("awt.21F")); //$NON-NLS-1$
+        // TODO - uncomment
+        //if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM) != 0)
+        //    throw new ImagingOpException("Unable to transform source");
+        }
+
+        return dst;
+    }
+
+    // TODO remove when method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst, int imageType) {
+        int srcStride, dstStride;
+        boolean skipChannel = false;
+        int channels;
+        int offsets[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_RGB:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                skipChannel = true;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY:
+            case BufferedImage.TYPE_BYTE_INDEXED: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in native code?
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1, 3 and 4 channels
+                    if (channels != 1 && channels != 3 && channels != 4) {
+                        return slowFilter(src, dst);
+                    }
+
+                    int dataTypeSize = DataBuffer.getDataTypeSize(srcSM.getDataType()) / 8;
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride() * dataTypeSize;
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride() * dataTypeSize;
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+                    // No IPP function for this type
+                    if (sppsm1.getDataType() == DataBuffer.TYPE_USHORT) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = sppsm1.getNumBands();
+                    // Have IPP functions for 1, 3 and 4 channels
+                    if (channels != 1 && channels != 3 && channels != 4) {
+                        return slowFilter(src, dst);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            sppsm1.getDataType() != sppsm2.getDataType() ||
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst);
+                        }
+                    }
+
+                    if (channels == 3) {
+                        channels = 4;
+                    }
+
+                    int dataTypeSize = DataBuffer.getDataTypeSize(sppsm1.getDataType()) / 8;
+
+                    srcStride = sppsm1.getScanlineStride() * dataTypeSize;
+                    dstStride = sppsm2.getScanlineStride() * dataTypeSize;
+                } else {
+                    return slowFilter(src, dst);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        double m00 = at.getScaleX();
+        double m01 = at.getShearX();
+        double m02 = at.getTranslateX();
+        double m10 = at.getShearY();
+        double m11 = at.getScaleY();
+        double m12 = at.getTranslateY();
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        return ippAffineTransform(
+            m00, m01, m02, m10, m11, m12,
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            iType, channels, skipChannel, offsets);
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private int slowFilter(Raster src, WritableRaster dst) {
+        // TODO: make correct interpolation
+        // TODO: what if there are different data types?
+
+        Rectangle srcBounds = src.getBounds();
+        Rectangle dstBounds = dst.getBounds();
+        Rectangle normDstBounds = new Rectangle(0, 0, dstBounds.width, dstBounds.height);
+        Rectangle bounds = getBounds2D(src).getBounds().intersection(normDstBounds);
+
+        AffineTransform inv = null;
+        try {
+             inv = at.createInverse();
+        } catch (NoninvertibleTransformException e) {
+            return -1;
+        }
+
+        double[] m = new double[6];
+        inv.getMatrix(m);
+
+        int minSrcX = srcBounds.x;
+        int minSrcY = srcBounds.y;
+        int maxSrcX = srcBounds.x + srcBounds.width;
+        int maxSrcY = srcBounds.y + srcBounds.height;
+
+        int minX = bounds.x + dstBounds.x;
+        int minY = bounds.y + dstBounds.y;
+        int maxX = minX + bounds.width;
+        int maxY = minY + bounds.height;
+
+        int hx = (int)(m[0] * 256);
+        int hy = (int)(m[1] * 256);
+        int vx = (int)(m[2] * 256);
+        int vy = (int)(m[3] * 256);
+        int sx = (int)(m[4] * 256) + hx * bounds.x + vx * bounds.y + (srcBounds.x) * 256;
+        int sy = (int)(m[5] * 256) + hy * bounds.x + vy * bounds.y + (srcBounds.y) * 256;
+
+        vx -= hx * bounds.width;
+        vy -= hy * bounds.width;
+
+        if (src.getTransferType() == dst.getTransferType()) {
+            for (int y = minY; y < maxY; y++) {
+                for (int x = minX; x < maxX; x++) {
+                    int px = sx >> 8;
+                    int py = sy >> 8;
+                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
+                        Object val = src.getDataElements(px , py , null);
+                        dst.setDataElements(x, y, val);
+                    }
+                    sx += hx;
+                    sy += hy;
+                }
+                sx += vx;
+                sy += vy;
+            }
+        } else {
+            float pixel[] = null;
+            for (int y = minY; y < maxY; y++) {
+                for (int x = minX; x < maxX; x++) {
+                    int px = sx >> 8;
+                    int py = sy >> 8;
+                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
+                        pixel = src.getPixel(px, py, pixel);
+                        dst.setPixel(x, y, pixel);
+                    }
+                    sx += hx;
+                    sy += hy;
+                }
+                sx += vx;
+                sy += vy;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Ipp affine transform.
+     * 
+     * @param m00 the m00
+     * @param m01 the m01
+     * @param m02 the m02
+     * @param m10 the m10
+     * @param m11 the m11
+     * @param m12 the m12
+     * @param src the src
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dst the dst
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param iType the i type
+     * @param channels the channels
+     * @param skipChannel the skip channel
+     * @param offsets the offsets
+     * 
+     * @return the int
+     */
+    private native int ippAffineTransform(
+            double m00, double m01,
+            double m02, double m10,
+            double m11, double m12,
+            Object src, int srcWidth, int srcHeight, int srcStride,
+            Object dst, int dstWidth, int dstHeight, int dstStride,
+            int iType, int channels, boolean skipChannel,
+            int offsets[]);
+}
\ No newline at end of file
diff --git a/awt/java/awt/image/AreaAveragingScaleFilter.java b/awt/java/awt/image/AreaAveragingScaleFilter.java
new file mode 100644
index 0000000..f4933db
--- /dev/null
+++ b/awt/java/awt/image/AreaAveragingScaleFilter.java
@@ -0,0 +1,253 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Arrays;
+
+
+/**
+ * The AreaAveragingScaleFilter class scales the source image using
+ * area averaging algorithm. This algorithm provides a source image
+ * with a new image containing the resampled image. 
+ */
+public class AreaAveragingScaleFilter extends ReplicateScaleFilter {
+
+    /** The Constant rgbCM. */
+    private static final ColorModel rgbCM = ColorModel.getRGBdefault();
+    
+    /** The Constant averagingFlags. */
+    private static final int averagingFlags = (ImageConsumer.TOPDOWNLEFTRIGHT |
+            ImageConsumer.COMPLETESCANLINES);
+
+    /** The reset. */
+    private boolean reset = true;   // Flag for used superclass filter
+    
+    /** The inited. */
+    private boolean inited = false; // All data inited
+
+    /** The sum_r. */
+    private int sum_r[]; // Array for average Red samples
+    
+    /** The sum_g. */
+    private int sum_g[]; // Array for average Green samples
+    
+    /** The sum_b. */
+    private int sum_b[]; // Array for average Blue samples
+    
+    /** The sum_a. */
+    private int sum_a[]; // Array for average Alpha samples
+
+    /** The buff. */
+    private int buff[];  // Stride buffer
+    
+    /** The avg factor. */
+    private int avgFactor;  // Global averaging factor
+
+    /** The cached dy. */
+    private int cachedDY;      // Cached number of the destination scanline 
+    
+    /** The cached dv rest. */
+    private int cachedDVRest;  // Cached value of rest src scanlines for sum 
+                               // pixel samples 
+                               // Because data if transfering by whole scanlines
+                               // we are caching only Y coordinate values
+    
+    /**
+     * Instantiates a new AreaAveragingScaleFilter object which scales
+     * a source image with the specified width and height.
+     * 
+     * @param width the scaled width of the image.
+     * @param height the scaled height of the image.
+     */
+    public AreaAveragingScaleFilter(int width, int height) {
+        super(width, height);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize) {
+        if(reset) {
+            super.setPixels(x, y, w, h, model, pixels, off, scansize);
+        } else {
+            setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize) {
+        if(reset) {
+            super.setPixels(x, y, w, h, model, pixels, off, scansize);
+        } else {
+            setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
+        }
+    }
+
+    @Override
+    public void setHints(int hints) {
+        super.setHints(hints);
+        reset = ((hints & averagingFlags) != averagingFlags);
+    }
+
+    /**
+     * This method implements the Area Averaging Scale filter.
+     * The description of algorithm is presented in Java API Specification.
+     * 
+     * Arrays sum_r, sum_g, sum_b, sum_a have length equals width of destination
+     * image. In each array's element is accumulating pixel's component values,
+     * proportional to the area which source pixels will occupy in destination
+     * image. Then that values will divide by Global averaging
+     * factor (area of the destination image) for receiving
+     * average values of destination pixels.
+     * 
+     * @param x - Src pixels X coordinate
+     * @param y - Src pixels Y coordinate
+     * @param w - width of the area of Src pixels
+     * @param h - height of the area of Src pixels
+     * @param model - Color Model of Src pixels
+     * @param pixels - array of Src pixels
+     * @param off - offset into the Src pixels array
+     * @param scansize - length of scanline in the pixels array
+     */
+    private void setFilteredPixels(int x, int y, int w, int h, ColorModel model, Object pixels, int off, int scansize){
+        if(!inited){
+            initialize();
+        }
+
+        int srcX, srcY, dx, dy;
+        int svRest, dvRest, shRest, dhRest, vDif, hDif;
+
+        if(y == 0){
+            dy = 0;
+            dvRest = srcHeight;
+        }else{
+            dy = cachedDY;
+            dvRest = cachedDVRest;
+        }
+
+        srcY = y;
+        svRest = destHeight;
+
+        int srcOff = off;
+        while (srcY < y + h) {
+            if (svRest < dvRest) {
+                vDif = svRest;
+            } else {
+                vDif = dvRest;
+            }
+
+            srcX = 0;
+            dx = 0;
+            shRest = destWidth;
+            dhRest = srcWidth;
+            while (srcX < w) {
+                if (shRest < dhRest) {
+                    hDif = shRest;
+                } else {
+                    hDif = dhRest;
+                }
+                int avg = hDif * vDif; // calculation of contribution factor
+
+                int rgb, pix;
+                if (pixels instanceof int[]) {
+                    pix = ((int[]) pixels)[srcOff + srcX];
+                } else {
+                    pix = ((byte[]) pixels)[srcOff + srcX] & 0xff;
+                }
+
+                rgb = model.getRGB(pix);
+                int a = rgb >>> 24;
+                int r = (rgb >> 16) & 0xff;
+                int g = (rgb >> 8) & 0xff;
+                int b = rgb & 0xff;
+
+                // accumulating pixel's component values
+                sum_a[dx] += a * avg;
+                sum_r[dx] += r * avg;
+                sum_g[dx] += g * avg;
+                sum_b[dx] += b * avg;
+
+                shRest -= hDif;
+                dhRest -= hDif;
+
+                if (shRest == 0) {
+                    srcX++;
+                    shRest = destWidth;
+                }
+
+                if (dhRest == 0) {
+                    dx++;
+                    dhRest = srcWidth;
+                }
+            }
+
+            svRest -= vDif;
+            dvRest -= vDif;
+
+            if (svRest == 0) {
+                svRest = destHeight;
+                srcY++;
+                srcOff += scansize;
+            }
+
+            if (dvRest == 0) {
+                // averaging destination pixel's values
+                for(int i = 0; i < destWidth; i++){
+                    int a = (sum_a[i] / avgFactor) & 0xff;
+                    int r = (sum_r[i] / avgFactor) & 0xff;
+                    int g = (sum_g[i] / avgFactor) & 0xff;
+                    int b = (sum_b[i] / avgFactor) & 0xff;
+                    int frgb = (a << 24) | (r << 16) | (g << 8) | b;
+                    buff[i] = frgb;
+                }
+                consumer.setPixels(0, dy, destWidth, 1, rgbCM, buff, 0,
+                        destWidth);
+                dy++;
+                dvRest = srcHeight;
+                Arrays.fill(sum_a, 0);
+                Arrays.fill(sum_r, 0);
+                Arrays.fill(sum_g, 0);
+                Arrays.fill(sum_b, 0);
+            }
+
+        }
+
+        cachedDY = dy;
+        cachedDVRest = dvRest;
+
+    }
+
+    /**
+     * Initialization of the auxiliary data.
+     */
+    private void initialize(){
+
+        sum_a = new int[destWidth]; 
+        sum_r = new int[destWidth]; 
+        sum_g = new int[destWidth]; 
+        sum_b = new int[destWidth]; 
+
+        buff = new int[destWidth];  
+        outpixbuf = buff;
+        avgFactor = srcWidth * srcHeight; 
+
+        inited = true;
+    }
+}
+
diff --git a/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java b/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java
new file mode 100644
index 0000000..ce85ddd
--- /dev/null
+++ b/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java
@@ -0,0 +1,153 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 23.11.2005
+ *
+ */
+package java.awt.image;
+
+import java.awt.Image;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferDouble;
+import java.awt.image.DataBufferFloat;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.DataBufferUShort;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.gl.GLVolatileImage;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class not part of public API. It useful for receiving package private
+ * data from other packages.
+ */
+class AwtImageBackdoorAccessorImpl extends AwtImageBackdoorAccessor {
+
+    static void init(){
+        inst = new AwtImageBackdoorAccessorImpl();
+    }
+
+    @Override
+    public Surface getImageSurface(Image image) {
+        if (image instanceof BufferedImage){
+            return ((BufferedImage)image).getImageSurface();
+        } else if (image instanceof GLVolatileImage){
+            return ((GLVolatileImage)image).getImageSurface();
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isGrayPallete(IndexColorModel icm){
+        return icm.isGrayPallete();
+    }
+
+    @Override
+    public Object getData(DataBuffer db) {
+        if (db instanceof DataBufferByte){
+            return ((DataBufferByte)db).getData();
+        } else if (db instanceof DataBufferUShort){
+            return ((DataBufferUShort)db).getData();
+        } else if (db instanceof DataBufferShort){
+            return ((DataBufferShort)db).getData();
+        } else if (db instanceof DataBufferInt){
+            return ((DataBufferInt)db).getData();
+        } else if (db instanceof DataBufferFloat){
+            return ((DataBufferFloat)db).getData();
+        } else if (db instanceof DataBufferDouble){
+            return ((DataBufferDouble)db).getData();
+        } else {
+            // awt.235=Wrong Data Buffer type : {0}
+            throw new IllegalArgumentException(Messages.getString("awt.235", //$NON-NLS-1$
+                    db.getClass()));
+        }
+    }
+
+    @Override
+    public int[] getDataInt(DataBuffer db) {
+        if (db instanceof DataBufferInt){
+            return ((DataBufferInt)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public byte[] getDataByte(DataBuffer db) {
+        if (db instanceof DataBufferByte){
+            return ((DataBufferByte)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public short[] getDataShort(DataBuffer db) {
+        if (db instanceof DataBufferShort){
+            return ((DataBufferShort)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public short[] getDataUShort(DataBuffer db) {
+        if (db instanceof DataBufferUShort){
+            return ((DataBufferUShort)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public double[] getDataDouble(DataBuffer db) {
+        if (db instanceof DataBufferDouble){
+            return ((DataBufferDouble)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public float[] getDataFloat(DataBuffer db) {
+        if (db instanceof DataBufferFloat){
+            return ((DataBufferFloat)db).getData();
+        }
+        return null;
+    }
+
+    @Override
+    public void addDataBufferListener(DataBuffer db, DataBufferListener listener) {
+        db.addDataBufferListener(listener);
+    }
+
+    @Override
+    public void removeDataBufferListener(DataBuffer db) {
+        db.removeDataBufferListener();
+    }
+
+    @Override
+    public void validate(DataBuffer db) {
+        db.validate();
+    }
+
+    @Override
+    public void releaseData(DataBuffer db) {
+        db.releaseData();
+    }
+}
diff --git a/awt/java/awt/image/BandCombineOp.java b/awt/java/awt/image/BandCombineOp.java
new file mode 100644
index 0000000..cd77a21
--- /dev/null
+++ b/awt/java/awt/image/BandCombineOp.java
@@ -0,0 +1,610 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 20, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BandCombineOp class translates coordinates from 
+ * coordinates in the source Raster to coordinates in 
+ * the destination Raster by an arbitrary linear combination 
+ * of the bands in a source Raster, using a specified matrix.
+ * The number of bands in the matrix should equal to 
+ * the number of bands in the source Raster plus 1.
+ */
+public class BandCombineOp implements RasterOp {
+    
+    /** The Constant offsets3c. */
+    static final int offsets3c[] = {16, 8, 0};
+    
+    /** The Constant offsets4ac. */
+    static final int offsets4ac[] = {16, 8, 0, 24};
+    
+    /** The Constant masks3c. */
+    static final int masks3c[] = {0xFF0000, 0xFF00, 0xFF};
+    
+    /** The Constant masks4ac. */
+    static final int masks4ac[] = {0xFF0000, 0xFF00, 0xFF, 0xFF000000};
+    
+    /** The Constant piOffsets. */
+    private static final int piOffsets[] = {0, 1, 2};
+    
+    /** The Constant piInvOffsets. */
+    private static final int piInvOffsets[] = {2, 1, 0};
+
+    /** The Constant TYPE_BYTE3C. */
+    private static final int TYPE_BYTE3C = 0;
+    
+    /** The Constant TYPE_BYTE4AC. */
+    private static final int TYPE_BYTE4AC = 1;
+    
+    /** The Constant TYPE_USHORT3C. */
+    private static final int TYPE_USHORT3C = 2;
+    
+    /** The Constant TYPE_SHORT3C. */
+    private static final int TYPE_SHORT3C = 3;
+
+    /** The mx width. */
+    private int mxWidth;
+    
+    /** The mx height. */
+    private int mxHeight;
+    
+    /** The matrix. */
+    private float matrix[][];
+    
+    /** The r hints. */
+    private RenderingHints rHints;
+
+    static {
+        // XXX - todo
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new BandCombineOp object with the specified
+     * matrix.
+     * 
+     * @param matrix the specified matrix for band combining.
+     * @param hints the RenderingHints.
+     */
+    public BandCombineOp(float matrix[][], RenderingHints hints) {
+        this.mxHeight = matrix.length;
+        this.mxWidth = matrix[0].length;
+        this.matrix = new float[mxHeight][mxWidth];
+
+        for (int i=0; i<mxHeight; i++){
+            System.arraycopy(matrix[i], 0, this.matrix[i], 0, mxWidth);
+        }
+
+        this.rHints = hints;
+    }
+
+    public final RenderingHints getRenderingHints(){
+        return this.rHints;
+    }
+
+    /**
+     * Gets the matrix associated with this BandCombineOp object.
+     * 
+     * @return the matrix associated with this BandCombineOp object.
+     */
+    public final float[][] getMatrix() {
+        float res[][] = new float[mxHeight][mxWidth];
+
+        for (int i=0; i<mxHeight; i++) {
+            System.arraycopy(matrix[i], 0, res[i], 0, mxWidth);
+        }
+
+        return res;
+    }
+
+    public final Point2D getPoint2D (Point2D srcPoint, Point2D dstPoint) {
+        if (dstPoint == null) {
+            dstPoint = new Point2D.Float();
+        }
+
+        dstPoint.setLocation(srcPoint);
+        return dstPoint;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src){
+        return src.getBounds();
+    }
+
+    public WritableRaster createCompatibleDestRaster (Raster src) {
+        int numBands = src.getNumBands();
+        if (mxWidth != numBands && mxWidth != (numBands+1) || numBands != mxHeight) {
+            // awt.254=Number of bands in the source raster ({0}) is
+            //          incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(Messages.getString("awt.254", //$NON-NLS-1$
+                    new Object[]{numBands, mxWidth, mxHeight}));
+        }
+
+        return src.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+    }
+
+    public WritableRaster filter(Raster src, WritableRaster dst) {
+        int numBands = src.getNumBands();
+
+        if (mxWidth != numBands && mxWidth != (numBands+1)) {
+            // awt.254=Number of bands in the source raster ({0}) is
+            //          incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(
+                    Messages.getString("awt.254", //$NON-NLS-1$
+                    new Object[]{numBands, mxWidth, mxHeight}));
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (dst.getNumBands() != mxHeight) {
+            // awt.255=Number of bands in the destination raster ({0}) is incompatible with the matrix [{1}x{2}]
+            throw new IllegalArgumentException(Messages.getString("awt.255", //$NON-NLS-1$
+                    new Object[]{dst.getNumBands(), mxWidth, mxHeight}));
+        }
+
+        // XXX - todo
+        //if (ippFilter(src, dst) != 0)
+        if (verySlowFilter(src, dst) != 0) {
+            // awt.21F=Unable to transform source
+            throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+        }
+
+        return dst;
+    }
+
+    /**
+     * The Class SampleModelInfo.
+     */
+    private static final class SampleModelInfo {
+        
+        /** The channels. */
+        int channels;
+        
+        /** The channels order. */
+        int channelsOrder[];
+        
+        /** The stride. */
+        int stride;
+    }
+
+    /**
+     * Check sample model.
+     * 
+     * @param sm the sm
+     * 
+     * @return the sample model info
+     */
+    private final SampleModelInfo checkSampleModel(SampleModel sm) {
+        SampleModelInfo ret = new SampleModelInfo();
+
+        if (sm instanceof PixelInterleavedSampleModel) {
+            // Check PixelInterleavedSampleModel
+            if (sm.getDataType() != DataBuffer.TYPE_BYTE) {
+                return null;
+            }
+
+            ret.channels = sm.getNumBands();
+            ret.stride = ((ComponentSampleModel) sm).getScanlineStride();
+            ret.channelsOrder = ((ComponentSampleModel) sm).getBandOffsets();
+
+        } else if (sm instanceof SinglePixelPackedSampleModel) {
+            // Check SinglePixelPackedSampleModel
+            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) sm;
+
+            ret.channels = sppsm1.getNumBands();
+            if (sppsm1.getDataType() != DataBuffer.TYPE_INT) {
+                return null;
+            }
+
+            // Check sample models
+            for (int i=0; i<ret.channels; i++) {
+                if (sppsm1.getSampleSize(i) != 8) {
+                    return null;
+                }
+            }
+
+            ret.channelsOrder = new int[ret.channels];
+            int bitOffsets[] = sppsm1.getBitOffsets();
+            for (int i=0; i<ret.channels; i++) {
+                if (bitOffsets[i] % 8 != 0) {
+                    return null;
+                }
+
+                ret.channelsOrder[i] = bitOffsets[i] / 8;
+            }
+
+            ret.channels = 4;
+            ret.stride = sppsm1.getScanlineStride() * 4;
+        } else {
+            return null;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private final int slowFilter(Raster src, WritableRaster dst) {
+        int res = 0;
+
+        SampleModelInfo srcInfo, dstInfo;
+        int offsets[] = null;
+
+        srcInfo = checkSampleModel(src.getSampleModel());
+        dstInfo = checkSampleModel(dst.getSampleModel());
+        if (srcInfo == null || dstInfo == null) {
+            return verySlowFilter(src, dst);
+        }
+
+        // Fill offsets if there's a child raster
+        if (src.getParent() != null || dst.getParent() != null) {
+            if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0 ||
+                    dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) {
+                offsets = new int[4];
+                offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+            }
+        }
+
+        int rmxWidth = (srcInfo.channels+1); // width of the reordered matrix
+        float reorderedMatrix[] = new float[rmxWidth*dstInfo.channels];
+        for (int j=0; j<dstInfo.channels; j++) {
+            if (j >= dstInfo.channelsOrder.length) {
+                continue;
+            }
+
+            for (int i=0; i<srcInfo.channels; i++) {
+                if (i >= srcInfo.channelsOrder.length) {
+                    break;
+                }
+
+                reorderedMatrix[dstInfo.channelsOrder[j]*rmxWidth + srcInfo.channelsOrder[i]] =
+                        matrix[j][i];
+            }
+            if (mxWidth == rmxWidth) {
+                reorderedMatrix[(dstInfo.channelsOrder[j]+1)*rmxWidth - 1] = matrix[j][mxWidth-1];
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        simpleCombineBands(
+                srcData, src.getWidth(), src.getHeight(), srcInfo.stride, srcInfo.channels,
+                dstData, dstInfo.stride, dstInfo.channels,
+                reorderedMatrix, offsets
+        );
+
+        return res;
+    }
+
+    /**
+     * Very slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private int verySlowFilter(Raster src, WritableRaster dst) {
+        int numBands = src.getNumBands();
+
+        int srcMinX = src.getMinX();
+        int srcY = src.getMinY();
+
+        int dstMinX = dst.getMinX();
+        int dstY = dst.getMinY();
+
+        int dX = src.getWidth();//< dst.getWidth() ? src.getWidth() : dst.getWidth();
+        int dY = src.getHeight();//< dst.getHeight() ? src.getHeight() : dst.getHeight();
+
+        float sample;
+        int srcPixels[] = new int[numBands*dX*dY];
+        int dstPixels[] = new int[mxHeight*dX*dY];
+
+        srcPixels = src.getPixels(srcMinX, srcY, dX, dY, srcPixels);
+
+        if (numBands == mxWidth) {
+            for (int i=0, j=0; i<srcPixels.length; i+=numBands) {
+                for (int dstB = 0; dstB < mxHeight; dstB++) {
+                    sample = 0f;
+                    for (int srcB = 0; srcB < numBands; srcB++) {
+                        sample += matrix[dstB][srcB] * srcPixels[i+srcB];
+                    }
+                    dstPixels[j++] = (int) sample;
+                }
+            }
+        } else {
+            for (int i=0, j=0; i<srcPixels.length; i+=numBands) {
+                for (int dstB = 0; dstB < mxHeight; dstB++) {
+                    sample = 0f;
+                    for (int srcB = 0; srcB < numBands; srcB++) {
+                        sample += matrix[dstB][srcB] * srcPixels[i+srcB];
+                    }
+                    dstPixels[j++] = (int) (sample + matrix[dstB][numBands]);
+                }
+            }
+        }
+
+        dst.setPixels(dstMinX, dstY, dX, dY, dstPixels);
+
+        return 0;
+    }
+
+    //TODO remove when method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst) {
+        boolean invertChannels;
+        boolean inPlace = (src == dst);
+        int type;
+        int srcStride, dstStride;
+        int offsets[] = null;
+
+        int srcBands = src.getNumBands();
+        int dstBands = dst.getNumBands();
+
+        if (
+                dstBands != 3 ||
+                (srcBands != 3 &&
+                !(srcBands == 4 &&
+                  matrix[0][3] == 0 &&
+                  matrix[1][3] == 0 &&
+                  matrix[2][3] == 0)
+                )
+        ) {
+            return slowFilter(src, dst);
+        }
+
+        SampleModel srcSM = src.getSampleModel();
+        SampleModel dstSM = dst.getSampleModel();
+
+        if (
+                srcSM instanceof SinglePixelPackedSampleModel &&
+                dstSM instanceof SinglePixelPackedSampleModel
+        ) {
+            // Check SinglePixelPackedSampleModel
+            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+            SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+            if (
+                    sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                    sppsm2.getDataType() != DataBuffer.TYPE_INT
+            ) {
+                return slowFilter(src, dst);
+            }
+
+            // Check sample models
+            if (
+                    !Arrays.equals(sppsm2.getBitOffsets(), offsets3c) ||
+                    !Arrays.equals(sppsm2.getBitMasks(), masks3c)
+            ) {
+                return slowFilter(src, dst);
+            }
+
+            if (srcBands == 3) {
+                if (
+                        !Arrays.equals(sppsm1.getBitOffsets(), offsets3c) ||
+                        !Arrays.equals(sppsm1.getBitMasks(), masks3c)
+                ) {
+                    return slowFilter(src, dst);
+                }
+            } else if (srcBands == 4) {
+                if (
+                        !Arrays.equals(sppsm1.getBitOffsets(), offsets4ac) ||
+                        !Arrays.equals(sppsm1.getBitMasks(), masks4ac)
+                ) {
+                    return slowFilter(src, dst);
+                }
+            }
+
+            type = TYPE_BYTE4AC;
+            invertChannels = true;
+
+            srcStride = sppsm1.getScanlineStride() * 4;
+            dstStride = sppsm2.getScanlineStride() * 4;
+        } else if (
+            srcSM instanceof PixelInterleavedSampleModel &&
+            dstSM instanceof PixelInterleavedSampleModel
+        ) {
+            if (srcBands != 3) {
+                return slowFilter(src, dst);
+            }
+
+            int srcDataType = srcSM.getDataType();
+
+            switch (srcDataType) {
+                case DataBuffer.TYPE_BYTE:
+                    type = TYPE_BYTE3C;
+                    break;
+                case DataBuffer.TYPE_USHORT:
+                    type = TYPE_USHORT3C;
+                    break;
+                case DataBuffer.TYPE_SHORT:
+                    type = TYPE_SHORT3C;
+                    break;
+                default:
+                    return slowFilter(src, dst);
+            }
+
+            // Check PixelInterleavedSampleModel
+            PixelInterleavedSampleModel pism1 = (PixelInterleavedSampleModel) srcSM;
+            PixelInterleavedSampleModel pism2 = (PixelInterleavedSampleModel) dstSM;
+
+            if (
+                    srcDataType != pism2.getDataType() ||
+                    pism1.getPixelStride() != 3 ||
+                    pism2.getPixelStride() != 3 ||
+                    !Arrays.equals(pism1.getBandOffsets(), pism2.getBandOffsets())
+            ) {
+                return slowFilter(src, dst);
+            }
+
+            if (Arrays.equals(pism1.getBandOffsets(), piInvOffsets)) {
+                invertChannels = true;
+            } else if (Arrays.equals(pism1.getBandOffsets(), piOffsets)) {
+                invertChannels = false;
+            } else {
+                return slowFilter(src, dst);
+            }
+
+            int dataTypeSize = DataBuffer.getDataTypeSize(srcDataType) / 8;
+
+            srcStride = pism1.getScanlineStride() * dataTypeSize;
+            dstStride = pism2.getScanlineStride() * dataTypeSize;
+        } else { // XXX - todo - IPP allows support for planar data also
+            return slowFilter(src, dst);
+        }
+
+        // Fill offsets if there's a child raster
+        if (src.getParent() != null || dst.getParent() != null) {
+            if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0 ||
+               dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) {
+                offsets = new int[4];
+                offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        float ippMatrix[] = new float[12];
+
+        if (invertChannels) {
+            // IPP treats big endian integers like BGR, so we have to
+            // swap columns 1 and 3 and rows 1 and 3
+            for (int i = 0; i < mxHeight; i++) {
+                ippMatrix[i*4] = matrix[2-i][2];
+                ippMatrix[i*4+1] = matrix[2-i][1];
+                ippMatrix[i*4+2] = matrix[2-i][0];
+
+                if (mxWidth == 4) {
+                    ippMatrix[i*4+3] = matrix[2-i][3];
+                } else if (mxWidth == 5) {
+                    ippMatrix[i*4+3] = matrix[2-i][4];
+                }
+            }
+        } else {
+            for (int i = 0; i < mxHeight; i++) {
+                ippMatrix[i*4] = matrix[i][0];
+                ippMatrix[i*4+1] = matrix[i][1];
+                ippMatrix[i*4+2] = matrix[i][2];
+
+                if (mxWidth == 4) {
+                    ippMatrix[i*4+3] = matrix[i][3];
+                } else if (mxWidth == 5) {
+                    ippMatrix[i*4+3] = matrix[i][4];
+                }
+            }
+        }
+
+        return ippColorTwist(
+                srcData, src.getWidth(), src.getHeight(), srcStride,
+                dstData, dst.getWidth(), dst.getHeight(), dstStride,
+                ippMatrix, type, offsets, inPlace);
+    }
+
+    /**
+     * Ipp color twist.
+     * 
+     * @param srcData the src data
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dstData the dst data
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param ippMatrix the ipp matrix
+     * @param type the type
+     * @param offsets the offsets
+     * @param inPlace the in place
+     * 
+     * @return the int
+     */
+    private final native int ippColorTwist(
+            Object srcData, int srcWidth, int srcHeight, int srcStride,
+            Object dstData, int dstWidth, int dstHeight, int dstStride,
+            float ippMatrix[], int type, int offsets[], boolean inPlace
+    );
+
+    /**
+     * Simple combine bands.
+     * 
+     * @param srcData the src data
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param srcChannels the src channels
+     * @param dstData the dst data
+     * @param dstStride the dst stride
+     * @param dstChannels the dst channels
+     * @param m the m
+     * @param offsets the offsets
+     * 
+     * @return the int
+     */
+    private final native int simpleCombineBands(
+            Object srcData, int srcWidth, int srcHeight, int srcStride, int srcChannels,
+            Object dstData, int dstStride, int dstChannels,
+            float m[], int offsets[]
+    );
+}
diff --git a/awt/java/awt/image/BandedSampleModel.java b/awt/java/awt/image/BandedSampleModel.java
new file mode 100644
index 0000000..392e44c
--- /dev/null
+++ b/awt/java/awt/image/BandedSampleModel.java
@@ -0,0 +1,426 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BandedSampleModel class provides samples of pixels in an image 
+ * which is stored in a band interleaved method. Each pixel's sample 
+ * takes one data element of the DataBuffer. The pixel stride for a 
+ * BandedSampleModel is one. 
+ */
+public final class BandedSampleModel extends ComponentSampleModel {
+
+    /**
+     * Creates the indices.
+     * 
+     * @param numBands the num bands
+     * 
+     * @return the int[]
+     */
+    private static int[] createIndices(int numBands) {
+        int indices[] = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            indices[i] = i;
+        }
+        return indices;
+    }
+
+    /**
+     * Creates the offsets.
+     * 
+     * @param numBands the num bands
+     * 
+     * @return the int[]
+     */
+    private static int[] createOffsets(int numBands) {
+        int offsets[] = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            offsets[i] = 0;
+        }
+        return offsets;
+    }
+
+    /**
+     * Instantiates a new BandedSampleModel object with the specified 
+     * data type of samples, the width, height and bands number
+     * of image data.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param numBands the number of bands.
+     */
+    public BandedSampleModel(int dataType, int w, int h, int numBands) {
+        this(dataType, w, h, w, BandedSampleModel.createIndices(numBands),
+                BandedSampleModel.createOffsets(numBands));
+    }
+
+    /**
+     * Instantiates a new BandedSampleModel object with the specified 
+     * data type of samples, the width, height and bands number
+     * of image data.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param scanlineStride the scanline stride of the of the image data.
+     * @param bankIndices the array of the bank indecies.
+     * @param bandOffsets the array of the band offsets.
+     */
+    public BandedSampleModel(int dataType, int w, int h, int scanlineStride,
+            int bankIndices[], int bandOffsets[]) {
+        super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new BandedSampleModel(dataType, w, h, w, bankIndices,
+                bandOffsets);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+        int size = scanlineStride * height;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size, numBanks);
+            break;
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size, numBanks);
+            break;
+        case DataBuffer.TYPE_FLOAT:
+            data = new DataBufferFloat(size, numBanks);
+            break;
+        case DataBuffer.TYPE_DOUBLE:
+            data = new DataBufferDouble(size, numBanks);
+            break;
+        }
+
+        return data;
+
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int[] bands) {
+        if (bands.length > numBands) {
+            // awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int indices[] = new int[bands.length];
+        int offsets[] = new int[bands.length];
+
+        for (int i = 0; i < bands.length; i++) {
+            indices[i] = bankIndices[bands[i]];
+            offsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new BandedSampleModel(dataType, width, height, scanlineStride,
+                indices, offsets);
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE: {
+            byte bdata[];
+
+            if (obj == null) {
+                bdata = new byte[numBands];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                bdata[i] = (byte) getSample(x, y, i, data);
+            }
+
+            obj = bdata;
+            break;
+        }
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT: {
+            short sdata[];
+
+            if (obj == null) {
+                sdata = new short[numBands];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                sdata[i] = (short) getSample(x, y, i, data);
+            }
+
+            obj = sdata;
+            break;
+        }
+        case DataBuffer.TYPE_INT: {
+            int idata[];
+
+            if (obj == null) {
+                idata = new int[numBands];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                idata[i] = getSample(x, y, i, data);
+            }
+
+            obj = idata;
+            break;
+        }
+        case DataBuffer.TYPE_FLOAT: {
+            float fdata[];
+
+            if (obj == null) {
+                fdata = new float[numBands];
+            } else {
+                fdata = (float[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                fdata[i] = getSampleFloat(x, y, i, data);
+            }
+
+            obj = fdata;
+            break;
+        }
+        case DataBuffer.TYPE_DOUBLE: {
+            double ddata[];
+
+            if (obj == null) {
+                ddata = new double[numBands];
+            } else {
+                ddata = (double[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                ddata[i] = getSampleDouble(x, y, i, data);
+            }
+
+            obj = ddata;
+            break;
+        }
+        }
+
+        return obj;
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElem(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b]);
+    }
+
+    @Override
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemDouble(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b]);
+    }
+
+    @Override
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemFloat(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b]);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = super.hashCode();
+        int tmp = hash >>> 8;
+        hash <<= 8;
+        hash |= tmp;
+
+        return hash ^ 0x55;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[] = (byte[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, bdata[i] & 0xff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sdata[] = (short[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, sdata[i] & 0xffff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int idata[] = (int[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, idata[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fdata[] = (float[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, fdata[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double ddata[] = (double[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, ddata[i], data);
+            }
+            break;
+        }
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemDouble(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemFloat(bankIndices[b], y * scanlineStride + x +
+               bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElem(bankIndices[b], y * scanlineStride + x +
+                       bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+
+    }
+
+}
+
diff --git a/awt/java/awt/image/BufferStrategy.java b/awt/java/awt/image/BufferStrategy.java
new file mode 100644
index 0000000..e0508f0
--- /dev/null
+++ b/awt/java/awt/image/BufferStrategy.java
@@ -0,0 +1,72 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.BufferCapabilities;
+import java.awt.Graphics;
+
+/**
+ * The BufferStrategy abstract class provides an opportunity 
+ * to organize the buffers for a Canvas or Window. The BufferStrategy
+ * implementation depends on hardware and software limitations.
+ * These limitations are detectible through the capabilities 
+ * object which can be obtained by the GraphicsConfiguration of the Canvas 
+ * or Window.
+ */
+public abstract class BufferStrategy {
+
+    /**
+     * Returns true if the drawing buffer was lost since the last call 
+     * of getDrawGraphics. 
+     * 
+     * @return true if the drawing buffer was lost since the last call 
+     * of getDrawGraphics, false otherwise.
+     */
+    public abstract boolean contentsLost();
+
+    /**
+     * Returns true if the drawing buffer is restored from a lost state. 
+     * 
+     * @return true if the drawing buffer is restored from a lost state,
+     * false otherwise.
+     */
+    public abstract boolean contentsRestored();
+
+    /**
+     * Gets the BufferCapabilities of BufferStrategy.
+     * 
+     * @return the BufferCapabilities of BufferStrategy.
+     */
+    public abstract BufferCapabilities getCapabilities();
+
+    /**
+     * Gets the Graphics object to use to draw to the buffer.
+     * 
+     * @return the Graphics object to use to draw to the buffer.
+     */
+    public abstract Graphics getDrawGraphics();
+
+    /**
+     * Shows the next available buffer.
+     */
+    public abstract void show();
+
+}
diff --git a/awt/java/awt/image/BufferedImage.java b/awt/java/awt/image/BufferedImage.java
new file mode 100644
index 0000000..d305d66
--- /dev/null
+++ b/awt/java/awt/image/BufferedImage.java
@@ -0,0 +1,931 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.image.BufferedImageSource;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * The BufferedImage class describes an Image which contains a buffer 
+ * of image data and includes a ColorModel and a Raster for this data.
+ * This class provides methods for obtaining and setting the Raster
+ * and for manipulating the ColorModel parameters.
+ */
+public class BufferedImage extends 
+Image implements WritableRenderedImage, Transparency{
+
+    /** 
+     * The Constant TYPE_CUSTOM indicates that Image type 
+     * is unknown. 
+     */
+    public static final int TYPE_CUSTOM = 0;
+
+    /** 
+     * The Constant TYPE_INT_RGB indicates an image with 
+     * 8 bit RGB color components, it has a DirectColorModel 
+     * without alpha. 
+     */
+    public static final int TYPE_INT_RGB = 1;
+
+    /** 
+     * The Constant TYPE_INT_ARGB indicates an image with 
+     * 8 bit RGBA color components, it has a DirectColorModel 
+     * with alpha. 
+     */
+    public static final int TYPE_INT_ARGB = 2;
+
+    /** 
+     * The Constant TYPE_INT_ARGB_PRE indicates an image with 
+     * 8 bit RGBA color components, it has a DirectColorModel 
+     * with alpha, and image data is premultiplied by alpha. 
+     */
+    public static final int TYPE_INT_ARGB_PRE = 3;
+
+    /** 
+     * The Constant TYPE_INT_BGR indicates an image with 
+     * 8 bit RGB color components, BGR color model 
+     * (with the colors Blue, Green, and Red). There is no 
+     * alpha. The image has a DirectColorModel. 
+     */
+    public static final int TYPE_INT_BGR = 4;
+
+    /** 
+     * The Constant TYPE_3BYTE_BGR indicates an image with 
+     * 8 bit RGB color components, BGR color model 
+     * (with the colors Blue, Green, and Red stored in 3 bytes). 
+     * There is no alpha. The image has a ComponentColorModel. 
+     */
+    public static final int TYPE_3BYTE_BGR = 5;
+
+    /** 
+     * The Constant TYPE_4BYTE_ABGR indicates an image with 
+     * 8 bit RGBA color components stored in 3 bytes and 1 byte of alpha.
+     * It has a ComponentColorModel with alpha.  
+     */
+    public static final int TYPE_4BYTE_ABGR = 6;
+
+    /** 
+     * The Constant TYPE_4BYTE_ABGR_PRE indicates an image with 
+     * 8 bit RGBA color components stored in 3 bytes and 1 byte 
+     * for alpha. The image has a ComponentColorModel with alpha. 
+     * The color data is premultiplied with alpha.
+     */
+    public static final int TYPE_4BYTE_ABGR_PRE = 7;
+
+    /** 
+     * The Constant TYPE_USHORT_565_RGB indicates an image with 
+     * 565 RGB color components (5-bits red, 6-bits green, 5-bits blue) 
+     * with no alpha. This image has a DirectColorModel. 
+     */
+    public static final int TYPE_USHORT_565_RGB = 8;
+
+    /** 
+     * The Constant TYPE_USHORT_555_RGB indicates an image with 
+     * 555 RGB color components (5-bits red, 5-bits green, 5-bits blue) 
+     * with no alpha. This image has a DirectColorModel. 
+     */
+    public static final int TYPE_USHORT_555_RGB = 9;
+
+    /** 
+     * The Constant TYPE_BYTE_GRAY indicates a unsigned byte 
+     * image. This image has a ComponentColorModel with 
+     * a CS_GRAY ColorSpace. 
+     */
+    public static final int TYPE_BYTE_GRAY = 10;
+
+    /** 
+     * The Constant TYPE_USHORT_GRAY indicates an unsigned short 
+     * image. This image has a ComponentColorModel with a CS_GRAY 
+     * ColorSpace. 
+     */
+    public static final int TYPE_USHORT_GRAY = 11;
+
+    /** 
+     * The Constant TYPE_BYTE_BINARY indicates an opaque byte-packed
+     * 1, 2 or 4 bit image. The image has an IndexColorModel without 
+     * alpha.  
+     */
+    public static final int TYPE_BYTE_BINARY = 12;
+
+    /** 
+     * The Constant TYPE_BYTE_INDEXED indicates an indexed byte image. 
+     */
+    public static final int TYPE_BYTE_INDEXED = 13;
+
+    /** The Constant ALPHA_MASK. */
+    private static final int ALPHA_MASK = 0xff000000;
+
+    /** The Constant RED_MASK. */
+    private static final int RED_MASK = 0x00ff0000;
+
+    /** The Constant GREEN_MASK. */
+    private static final int GREEN_MASK = 0x0000ff00;
+
+    /** The Constant BLUE_MASK. */
+    private static final int BLUE_MASK = 0x000000ff;
+
+    /** The Constant RED_BGR_MASK. */
+    private static final int RED_BGR_MASK = 0x000000ff;
+
+    /** The Constant GREEN_BGR_MASK. */
+    private static final int GREEN_BGR_MASK = 0x0000ff00;
+
+    /** The Constant BLUE_BGR_MASK. */
+    private static final int BLUE_BGR_MASK = 0x00ff0000;
+
+    /** The Constant RED_565_MASK. */
+    private static final int RED_565_MASK = 0xf800;
+
+    /** The Constant GREEN_565_MASK. */
+    private static final int GREEN_565_MASK = 0x07e0;
+
+    /** The Constant BLUE_565_MASK. */
+    private static final int BLUE_565_MASK = 0x001f;
+
+    /** The Constant RED_555_MASK. */
+    private static final int RED_555_MASK = 0x7c00;
+
+    /** The Constant GREEN_555_MASK. */
+    private static final int GREEN_555_MASK = 0x03e0;
+
+    /** The Constant BLUE_555_MASK. */
+    private static final int BLUE_555_MASK = 0x001f;
+
+    /** The cm. */
+    private ColorModel cm;
+
+    /** The raster. */
+    private final WritableRaster raster;
+
+    /** The image type. */
+    private final int imageType;
+
+    /** The properties. */
+    private Hashtable<?, ?> properties;
+
+    // Surface of the Buffered Image - used for blitting one Buffered Image 
+    // on the other one or on the Component
+    /** The image surf. */
+    private final ImageSurface imageSurf;
+
+    /**
+     * Instantiates a new BufferedImage with the specified ColorModel,
+     * and WritableRaster objects. The Raster data can be
+     * be divided or multiplied by alpha. It depends on the 
+     * alphaPremultiplied state in the ColorModel.
+     * 
+     * @param cm the ColorModel of the new image.
+     * @param raster the WritableRaster of the new image.
+     * @param isRasterPremultiplied if true the data of the specified
+     * Raster is premultiplied by alpha.
+     * @param properties the properties of new Image.
+     */
+    public BufferedImage(ColorModel cm, WritableRaster raster,
+            boolean isRasterPremultiplied, Hashtable<?, ?> properties) {
+        if (!cm.isCompatibleRaster(raster)) {
+            // awt.4D=The raster is incompatible with this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
+        }
+
+        if (raster.getMinX() != 0 || raster.getMinY() != 0) {
+            // awt.228=minX or minY of this raster not equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.228")); //$NON-NLS-1$
+        }
+
+        this.cm  = cm;
+        this.raster = raster;
+        this.properties = properties;
+
+        coerceData(isRasterPremultiplied);
+
+        imageType = Surface.getType(cm, raster);
+
+        imageSurf = createImageSurface(imageType);
+    }
+
+    /**
+     * Instantiates a new BufferedImage with the specified width, height
+     * predefined image type (TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED) 
+     * and the specified IndexColorModel.
+     * 
+     * @param width the width of new image.
+     * @param height the height of new image.
+     * @param imageType the predefined image type. 
+     * @param cm the specified IndexColorModel.
+     */
+    public BufferedImage(int width, int height, int imageType,
+            IndexColorModel cm) {
+        switch (imageType) {
+        case TYPE_BYTE_BINARY:
+            if (cm.hasAlpha()) {
+                // awt.227=This image type can't have alpha
+                throw new IllegalArgumentException(Messages.getString("awt.227")); //$NON-NLS-1$
+            }
+            int pixel_bits = 0;
+            int mapSize = cm.getMapSize();
+            if (mapSize <= 2) {
+                pixel_bits = 1;
+            } else if (mapSize <= 4) {
+                pixel_bits = 2;
+            } else if (mapSize <= 16) {
+                pixel_bits = 4;
+            } else {
+                // awt.221=The imageType is TYPE_BYTE_BINARY and the color map has more than 16 entries
+                throw new IllegalArgumentException(Messages.getString("awt.221")); //$NON-NLS-1$
+            }
+
+            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width,
+                    height, 1, pixel_bits, null);
+            break;
+
+        case TYPE_BYTE_INDEXED:
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, 1, null);
+            break;
+
+        default:
+            // awt.222=The imageType is not TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED
+            throw new IllegalArgumentException(Messages.getString("awt.222")); //$NON-NLS-1$
+
+        }
+
+        if (!cm.isCompatibleRaster(raster)) {
+            // awt.223=The imageType is not compatible with ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.223")); //$NON-NLS-1$
+        }
+
+        this.cm = cm;
+        this.imageType = imageType;
+        imageSurf = createImageSurface(imageType);
+
+    }
+
+    /**
+     * Instantiates a new BufferedImage with the specified width, height
+     * and predefined image type.
+     * 
+     * @param width the width of new image.
+     * @param height the height of new image.
+     * @param imageType the predefined image type. 
+     */
+    public BufferedImage(int width, int height, int imageType) {
+
+        switch (imageType) {
+        case TYPE_INT_RGB:
+            cm = new DirectColorModel(24, RED_MASK, GREEN_MASK, BLUE_MASK);
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_INT_ARGB:
+            cm = ColorModel.getRGBdefault();
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_INT_ARGB_PRE:
+            cm = new DirectColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    32,
+                    RED_MASK,
+                    GREEN_MASK,
+                    BLUE_MASK,
+                    ALPHA_MASK,
+                    true,
+                    DataBuffer.TYPE_INT);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_INT_BGR:
+            cm = new DirectColorModel(24,
+                    RED_BGR_MASK,
+                    GREEN_BGR_MASK,
+                    BLUE_BGR_MASK);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_3BYTE_BGR: {
+            int bits[] = { 8, 8, 8 };
+            int bandOffsets[] = { 2, 1, 0 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    bits, 
+                    false, 
+                    false, 
+                    Transparency.OPAQUE, 
+                    DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, width * 3, 3, bandOffsets, null);
+            }
+            break;
+
+        case TYPE_4BYTE_ABGR: {
+            int bits[] = { 8, 8, 8, 8 };
+            int bandOffsets[] = { 3, 2, 1, 0 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    bits, 
+                    true, 
+                    false, 
+                    Transparency.TRANSLUCENT, 
+                    DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, width * 4, 4, bandOffsets, null);
+            }
+            break;
+
+        case TYPE_4BYTE_ABGR_PRE: {
+            int bits[] = { 8, 8, 8, 8 };
+            int bandOffsets[] = { 3, 2, 1, 0 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    bits, 
+                    true, 
+                    true, 
+                    Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, width * 4, 4, bandOffsets, null);
+            }
+            break;
+
+        case TYPE_USHORT_565_RGB:
+            cm = new DirectColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    16,
+                    RED_565_MASK,
+                    GREEN_565_MASK,
+                    BLUE_565_MASK,
+                    0,
+                    false,
+                    DataBuffer.TYPE_USHORT);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_USHORT_555_RGB:
+            cm = new DirectColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                    15,
+                    RED_555_MASK,
+                    GREEN_555_MASK,
+                    BLUE_555_MASK,
+                    0,
+                    false,
+                    DataBuffer.TYPE_USHORT);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            break;
+
+        case TYPE_BYTE_GRAY: {
+            int bits[] = { 8 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                    bits, 
+                    false, 
+                    false, 
+                    Transparency.OPAQUE, 
+                    DataBuffer.TYPE_BYTE);
+
+            raster = cm.createCompatibleWritableRaster(width, height);
+            }
+            break;
+
+        case TYPE_USHORT_GRAY: {
+            int bits[] = { 16 };
+            cm = new ComponentColorModel(
+                    ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                    bits, 
+                    false, 
+                    false, 
+                    Transparency.OPAQUE, 
+                    DataBuffer.TYPE_USHORT);
+            raster = cm.createCompatibleWritableRaster(width, height);
+            }
+            break;
+
+        case TYPE_BYTE_BINARY: {
+            int colorMap[] = { 0, 0xffffff };
+            cm = new IndexColorModel(1, 2, colorMap, 0, false, -1,
+                    DataBuffer.TYPE_BYTE);
+
+            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, width,
+                    height, 1, 1, null);
+            }
+            break;
+
+        case TYPE_BYTE_INDEXED: {
+            int colorMap[] = new int[256];
+            int i = 0;
+            for (int r = 0; r < 256; r += 51) {
+                for (int g = 0; g < 256; g += 51) {
+                    for (int b = 0; b < 256; b += 51) {
+                        colorMap[i] = (r << 16) | (g << 8) | b;
+                        i++;
+                    }
+                }
+            }
+
+            int gray = 0x12;
+            for (; i < 256; i++, gray += 6) {
+                colorMap[i] = (gray << 16) | (gray << 8) | gray;
+            }
+            cm = new IndexColorModel(8, 256, colorMap, 0, false, -1,
+                    DataBuffer.TYPE_BYTE);
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
+                    width, height, 1, null);
+
+            }
+            break;
+        default:
+            // awt.224=Unknown image type
+            throw new IllegalArgumentException(Messages.getString("awt.224")); //$NON-NLS-1$
+        }
+        this.imageType = imageType;
+        imageSurf = createImageSurface(imageType);
+    }
+
+    @Override
+    public Object getProperty(String name, ImageObserver observer) {
+        return getProperty(name);
+    }
+
+    public Object getProperty(String name) {
+        if(name == null) {
+            // awt.225=Property name is null
+            throw new NullPointerException(Messages.getString("awt.225")); //$NON-NLS-1$
+        }
+        if (properties == null) {
+            return Image.UndefinedProperty;
+        }
+        Object property = properties.get(name);
+        if (property == null) {
+            property = Image.UndefinedProperty;
+        }
+        return property;
+    }
+
+    public WritableRaster copyData(WritableRaster outRaster) {
+        if (outRaster == null) {
+            outRaster = Raster.createWritableRaster(raster.getSampleModel(),
+                    new Point(raster.getSampleModelTranslateX(),
+                            raster.getSampleModelTranslateY()));
+        }
+
+        int w = outRaster.getWidth();
+        int h = outRaster.getHeight();
+        int minX = outRaster.getMinX();
+        int minY = outRaster.getMinY();
+
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outRaster.setDataElements(minX, minY, w, h, data);
+
+        return outRaster;
+    }
+
+    public Raster getData(Rectangle rect) {
+        int minX = rect.x;
+        int minY = rect.y;
+        int w = rect.width;
+        int h = rect.height;
+
+        SampleModel sm = raster.getSampleModel();
+        SampleModel nsm = sm.createCompatibleSampleModel(w, h);
+        WritableRaster outr = Raster.createWritableRaster(nsm, 
+                rect.getLocation());
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outr.setDataElements(minX, minY, w, h, data);
+        return outr;
+    }
+
+    public Vector<RenderedImage> getSources() {
+        return null;
+    }
+
+    public String[] getPropertyNames() {
+        if (properties == null) {
+            return null;
+        }
+        Vector<String> v = new Vector<String>();
+        for (Enumeration<?> e = properties.keys(); e.hasMoreElements();) {
+            try {
+                v.add((String) e.nextElement());
+            } catch (ClassCastException ex) {
+            }
+        }
+        int size = v.size();
+        if (size > 0) {
+            String names[] = new String[size];
+            for (int i = 0; i < size; i++) {
+                names[i] = v.elementAt(i);
+            }
+            return names;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the string representation of this BufferedImage object.
+     * 
+     * @return the string representation of this BufferedImage object.
+     */
+    @Override
+    public String toString() {
+        return "BufferedImage@" + Integer.toHexString(hashCode()) + //$NON-NLS-1$
+            ": type = " + imageType + " " + cm + " " + raster; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    public WritableRaster getWritableTile(int tileX, int tileY) {
+        return raster;
+    }
+
+    /**
+     * Gets the WritableRaster of this BufferedImage.
+     * 
+     * @return the WritableRaster of this BufferedImage.
+     */
+    public WritableRaster getRaster() {
+        return raster;
+    }
+
+    /**
+     * Gets a WritableRaster object which contains the alpha channel of 
+     * BufferedImage object with ColorModel objects that supports 
+     * a separate alpha channel such as ComponentColorModel 
+     * or DirectColorModel.
+     * 
+     * @return the WritableRaster object which contains the alpha 
+     * channel of this BufferedImage. 
+     */
+    public WritableRaster getAlphaRaster() {
+        return cm.getAlphaRaster(raster);
+    }
+
+    public void removeTileObserver(TileObserver to) {
+    }
+
+    public void addTileObserver(TileObserver to) {
+    }
+
+    public SampleModel getSampleModel() {
+        return raster.getSampleModel();
+    }
+
+    public void setData(Raster r) {
+
+        Rectangle from = r.getBounds();
+        Rectangle to = raster.getBounds();
+        Rectangle intersection = to.intersection(from);
+
+        int minX = intersection.x;
+        int minY = intersection.y;
+        int w = intersection.width;
+        int h = intersection.height;
+
+        Object data = null;
+
+        data = r.getDataElements(minX, minY, w, h, data);
+        raster.setDataElements(minX, minY, w, h, data);
+    }
+
+    public Raster getTile(int tileX, int tileY) {
+        if (tileX == 0 && tileY == 0) {
+            return raster;
+        }
+        // awt.226=Both tileX and tileY are not equal to 0
+        throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.226")); //$NON-NLS-1$
+    }
+
+    public Raster getData() {
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+
+        WritableRaster outr = Raster.createWritableRaster(
+                raster.getSampleModel(),
+                new Point(raster.getSampleModelTranslateX(),
+                raster.getSampleModelTranslateY()));
+
+        Object data = null;
+
+        data = raster.getDataElements(minX, minY, w, h, data);
+        outr.setDataElements(minX, minY, w, h, data);
+
+        return outr;
+    }
+
+    @Override
+    public ImageProducer getSource() {
+        return new BufferedImageSource(this, properties);
+    }
+
+    @Override
+    public int getWidth(ImageObserver observer) {
+        return raster.getWidth();
+    }
+
+    @Override
+    public int getHeight(ImageObserver observer) {
+        return raster.getHeight();
+    }
+
+    public ColorModel getColorModel() {
+        return cm;
+    }
+
+    /**
+     * Gets the rectangular area of this BufferedImage as a subimage.
+     * 
+     * @param x the x coordinate.
+     * @param y the y coordinate.
+     * @param w the width of the subimage.
+     * @param h the height of the subimage.
+     * 
+     * @return the BufferedImage.
+     */
+    public BufferedImage getSubimage(int x, int y, int w, int h) {
+        WritableRaster wr = raster.createWritableChild(x, y, w, h, 0, 0, null);
+        return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), properties);
+    }
+
+    public Point[] getWritableTileIndices() {
+        Point points[] = new Point[1];
+        points[0] = new Point(0, 0);
+        return points;
+    }
+
+    /**
+     * Creates the Graphics2D object which allows to draw into 
+     * this BufferedImage.
+     * 
+     * @return the graphics2D object.
+     */
+    public Graphics2D createGraphics() {
+        GraphicsEnvironment ge = 
+            GraphicsEnvironment.getLocalGraphicsEnvironment();
+        //return ge.createGraphics(this);
+        //???AWT hack, FIXME
+        //return AndroidGraphics2D.getInstance();
+        //throw new RuntimeException("Not implemented!");
+        return null;
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        return createGraphics();
+    }
+
+    /**
+     * Coerces the data to achieve the state which is specified by 
+     * the isAlphaPremultiplied variable. 
+     * 
+     * @param isAlphaPremultiplied the is alpha premultiplied state.
+     */
+    public void coerceData(boolean isAlphaPremultiplied) {
+        if (cm.hasAlpha() && 
+                cm.isAlphaPremultiplied() != isAlphaPremultiplied) {
+            cm = cm.coerceData(raster, isAlphaPremultiplied);
+        }
+    }
+
+    /**
+     * Gets an array of colors in the TYPE_INT_ARGB color model and 
+     * default sRGB colorspace of the specified area of this
+     * BufferedImage. The result array is composed by the following
+     * algirithm:
+     * <p> 
+     * pixel   = rgbArray[offset + (y-startY)*scansize + (x-startX)]
+     * 
+     * @param startX the start X area coordinate. 
+     * @param startY the start Y area coordinate.
+     * @param w the width of the area. 
+     * @param h the height of the area.
+     * @param rgbArray the result array will be stored to this array.
+     * @param offset the offset of the rgbArray array. 
+     * @param scansize the scanline stride for the rgbArray.
+     * 
+     * @return an array of colors for the specified area.
+     */
+    public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray,
+            int offset, int scansize) {
+        if (rgbArray == null) {
+            rgbArray = new int[offset + h * scansize];
+        }
+
+        int off = offset;
+        for (int y = startY; y < startY + h; y++, off += scansize) {
+            int i = off;
+            for (int x = startX; x < startX + w; x++, i++) {
+                rgbArray[i] = cm.getRGB(raster.getDataElements(x, y, null));
+            }
+        }
+        return rgbArray;
+    }
+
+    /**
+     * Sets RGB values from the specified array to the specified
+     * BufferedImage area. The pixels are in the default RGB color model 
+     * (TYPE_INT_ARGB) and default sRGB color space.
+     * 
+     * @param startX the start X coordinate.
+     * @param startY the start Y coordinate.
+     * @param w the width of the BufferedImage area.
+     * @param h the height of the BufferedImage area.
+     * @param rgbArray the array of RGB values.
+     * @param offset the offset of the rgbArray array. 
+     * @param scansize the scanline stride for the rgbArray.
+     */
+    public void setRGB(int startX, int startY, int w, int h, int[] rgbArray,
+            int offset, int scansize) {
+        int off = offset;
+        for (int y = startY; y < startY + h; y++, off += scansize) {
+            int i = off;
+            for (int x = startX; x < startX + w; x++, i++) {
+                raster.setDataElements(x, y, 
+                        cm.getDataElements(rgbArray[i], null));
+            }
+        }
+    }
+
+    /**
+     * Sets a the specified RGB value to the specified pixel of
+     * this BufferedImage. The pixel should be in the default 
+     * RGB color model (TYPE_INT_ARGB) and default sRGB color space. 
+     *  
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param rgb the RGB value to be set.
+     */
+    public synchronized void setRGB(int x, int y, int rgb) {
+        raster.setDataElements(x, y, cm.getDataElements(rgb, null));
+    }
+
+    public boolean isTileWritable(int tileX, int tileY) {
+        if (tileX == 0 && tileY == 0) {
+            return true;
+        }
+        // awt.226=Both tileX and tileY are not equal to 0
+        throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.226")); //$NON-NLS-1$
+    }
+
+    public void releaseWritableTile(int tileX, int tileY) {
+    }
+
+    /**
+     * Gets a color in the TYPE_INT_ARGB color model and default 
+     * sRGB colorspace of the specified pixel. 
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * 
+     * @return the color of the specified pixel in the TYPE_INT_ARGB 
+     * color model and default sRGB colorspace. 
+     */
+    public int getRGB(int x, int y) {
+        return cm.getRGB(raster.getDataElements(x, y, null));
+    }
+
+    /**
+     * Returnes true if alpha is premultiplied, 
+     * false if alpha is not premultiplied or there is no alpha.
+     * 
+     * @return true if alpha is premultiplied, 
+     * false if alpha is not premultiplied or there is no alpha.
+     */
+    public boolean isAlphaPremultiplied() {
+        return cm.isAlphaPremultiplied();
+    }
+
+    public boolean hasTileWriters() {
+        return true;
+    }
+
+    @Override
+    public void flush() {
+        imageSurf.dispose();
+    }
+
+    public int getWidth() {
+        return raster.getWidth();
+    }
+
+    /**
+     * Gets the image type.
+     * 
+     * @return the image type.
+     */
+    public int getType() {
+        return imageType;
+    }
+
+    public int getTileWidth() {
+        return raster.getWidth();
+    }
+
+    public int getTileHeight() {
+        return raster.getHeight();
+    }
+
+    public int getTileGridYOffset() {
+        return raster.getSampleModelTranslateY();
+    }
+
+    public int getTileGridXOffset() {
+        return raster.getSampleModelTranslateX();
+    }
+
+    public int getNumYTiles() {
+        return 1;
+    }
+
+    public int getNumXTiles() {
+        return 1;
+    }
+
+    public int getMinY() {
+        return raster.getMinY();
+    }
+
+    public int getMinX() {
+        return raster.getMinX();
+    }
+
+    public int getMinTileY() {
+        return 0;
+    }
+
+    public int getMinTileX() {
+        return 0;
+    }
+
+    public int getHeight() {
+        return raster.getHeight();
+    }
+
+    /**
+     * Creates the image surface.
+     * 
+     * @param type the type
+     * 
+     * @return the image surface
+     */
+    private ImageSurface createImageSurface(int type) {
+        return new ImageSurface(getColorModel(), getRaster(), type);
+    }
+
+    /**
+     * Gets the image surface.
+     * 
+     * @return the image surface
+     */
+    ImageSurface getImageSurface() {
+        return imageSurf;
+    }
+
+    public int getTransparency() {
+        return cm.getTransparency();
+    }
+}
+
diff --git a/awt/java/awt/image/BufferedImageFilter.java b/awt/java/awt/image/BufferedImageFilter.java
new file mode 100644
index 0000000..44b3c2e
--- /dev/null
+++ b/awt/java/awt/image/BufferedImageFilter.java
@@ -0,0 +1,375 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The BufferedImageFilter class provides filtering operations to 
+ * the BufferedImage objects using operators which implement
+ * BufferedImageOp interface.
+ */
+public class BufferedImageFilter extends ImageFilter implements Cloneable {
+    
+    /** The Constant accessor. */
+    private static final AwtImageBackdoorAccessor accessor = AwtImageBackdoorAccessor.getInstance();
+
+    /** The op. */
+    private BufferedImageOp op;
+
+    /** The raster. */
+    private WritableRaster raster;
+
+    /** The i data. */
+    private int iData[];
+    
+    /** The b data. */
+    private byte bData[];
+
+    /** The width. */
+    private int width;
+    
+    /** The height. */
+    private int height;
+
+    /** The cm. */
+    private ColorModel cm;
+
+    /** The forced rgb. */
+    private boolean forcedRGB = false;
+    
+    /** The transfer type. */
+    private int transferType = DataBuffer.TYPE_UNDEFINED;
+
+    /**
+     * Instantiates a new BufferedImageFilter with the specified
+     * BufferedImageOp operator.
+     * 
+     * @param op the specified BufferedImageOp operator.
+     * 
+     * @throws NullPointerException if BufferedImageOp is null.
+     */
+    public BufferedImageFilter(BufferedImageOp op) {
+        if (op == null) {
+            throw new NullPointerException(Messages.getString("awt.05")); //$NON-NLS-1$
+        }
+        this.op = op;
+    }
+
+    /**
+     * Gets the BufferedImageOp operator associated with this 
+     * BufferedImageFilter object.
+     * 
+     * @return the BufferedImageOp associated with this 
+     * BufferedImageFilter object.
+     */
+    public BufferedImageOp getBufferedImageOp() {
+        return op;
+    }
+
+    @Override
+    public void setDimensions(int width, int height) {
+        this.width = width;
+        this.height = height;
+        // Stop image consuming if no pixels expected.
+        if (width <= 0 || height <= 0) {
+            consumer.imageComplete(ImageConsumer.STATICIMAGEDONE);
+            reset();
+        }
+    }
+
+    @Override
+    public void setColorModel(ColorModel model) {
+        if (this.cm != null && this.cm != model && raster != null) {
+            forceRGB();
+        } else {
+            this.cm = model;
+        }
+    }
+
+    @Override
+    public void setPixels(
+            int x, int y, int
+            w, int h,
+            ColorModel model, byte[] pixels,
+            int off, int scansize
+    ) {
+        setPixels(x, y, w, h, model, pixels, off, scansize, true);
+    }
+
+    @Override
+    public void setPixels(
+            int x, int y,
+            int w, int h,
+            ColorModel model, int[] pixels,
+            int off, int scansize
+    ) {
+        setPixels(x, y, w, h, model, pixels, off, scansize, false);
+    }
+
+    @Override
+    public void imageComplete(int status) {
+        if (status == STATICIMAGEDONE || status == SINGLEFRAMEDONE) {
+            BufferedImage bim = new BufferedImage(cm, raster, cm.isAlphaPremultiplied, null);
+            bim = op.filter(bim, null);
+            DataBuffer dstDb = bim.getRaster().getDataBuffer();
+            ColorModel dstCm = bim.getColorModel();
+            int dstW = bim.getWidth();
+            int dstH = bim.getHeight();
+
+            consumer.setDimensions(dstW, dstH);
+
+            if (dstDb.getDataType() == DataBuffer.TYPE_INT) {
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, accessor.getDataInt(dstDb), 0, dstW);
+            } else if (dstDb.getDataType() == DataBuffer.TYPE_BYTE) {
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, accessor.getDataByte(dstDb), 0, dstW);
+            } else {
+                int dstData[] = bim.getRGB(0, 0, dstW, dstH, null, 0, dstW);
+                dstCm = ColorModel.getRGBdefault();
+                consumer.setColorModel(dstCm);
+                consumer.setPixels(0, 0, dstW, dstH, dstCm, dstData, 0, dstW);
+            }
+        } else if (status == IMAGEERROR || status == IMAGEABORTED) {
+            reset();
+        }
+
+        consumer.imageComplete(status);
+    }
+
+    /**
+     * Sets the pixels.
+     * 
+     * @param x the x
+     * @param y the y
+     * @param w the w
+     * @param h the h
+     * @param model the model
+     * @param pixels the pixels
+     * @param off the off
+     * @param scansize the scansize
+     * @param isByteData the is byte data
+     */
+    private void setPixels(
+            int x, int y,
+            int w, int h,
+            ColorModel model, Object pixels,
+            int off, int scansize, boolean isByteData
+    ) {
+        // Check bounds
+        // Need to copy only the pixels that will fit into the destination area
+        if (x < 0) {
+            w -= x;
+            off += x;
+            x = 0;
+        }
+
+        if (y < 0) {
+            h -= y;
+            off += y * scansize;
+            y = 0;
+        }
+
+        if (x + w > width) {
+            w = width - x;
+        }
+
+        if (y + h > height) {
+            h = height - y;
+        }
+
+        if (w <= 0 || h <= 0) {
+            return;
+        }
+
+        // Check model
+        if (this.cm == null) {
+            setColorModel(model);
+        } else if (model == null) {
+            model = this.cm;
+        } else if (!model.equals(this.cm)) {
+            forceRGB();
+        }
+
+        boolean canArraycopy;
+        // Process pixels
+        switch(transferType) {
+            case DataBuffer.TYPE_UNDEFINED: {
+                if (isByteData) {
+                    transferType = DataBuffer.TYPE_BYTE;
+                    createRaster(transferType);
+                    //bData = new byte[width*height];
+                    canArraycopy = !forcedRGB;
+                    break;
+                }
+                transferType = DataBuffer.TYPE_INT;
+                createRaster(transferType);
+                //iData = new int[width*height];
+                canArraycopy = !forcedRGB || model.equals(ColorModel.getRGBdefault());
+                break;
+            } // And proceed to copy the pixels
+            case DataBuffer.TYPE_INT: {
+                if (isByteData) { // There are int data already but the new data are bytes
+                    forceRGB();
+                    canArraycopy = false;
+                    break;
+                } else if (!forcedRGB || model.equals(ColorModel.getRGBdefault())) {
+                    canArraycopy = true;
+                    break;
+                } // Else fallback to the RGB conversion
+            }
+            case DataBuffer.TYPE_BYTE: {
+                if (isByteData && !forcedRGB) {
+                    canArraycopy = true;
+                    break;
+                }
+
+                // RGB conversion
+                canArraycopy = false;
+                break;
+            } default: {
+                throw new IllegalStateException(Messages.getString("awt.06")); //$NON-NLS-1$
+            }
+        }
+
+        off += x;
+        int maxOffset = off + h * scansize;
+        int dstOffset = x + y * width;
+
+        if (canArraycopy) {
+            Object dstArray = isByteData ? (Object) bData : (Object) iData;
+            for (; off < maxOffset; off += scansize, dstOffset += width) {
+                System.arraycopy(pixels, off, dstArray, dstOffset, w);
+            }
+        } else {
+            // RGB conversion
+            for (; off < maxOffset; off += scansize, dstOffset += width) {
+                int srcPos = off;
+                int dstPos = dstOffset;
+                int maxDstPos = dstOffset + w;
+                for (; dstPos < maxDstPos; dstPos++, srcPos++) {
+                    iData[dstPos] = model.getRGB(
+                            isByteData ?
+                            ((byte[])pixels)[srcPos] :
+                            ((int[])pixels)[srcPos]
+                    );
+                }
+            }
+        }
+    }
+
+    /**
+     * Force rgb.
+     */
+    private void forceRGB() {
+        if (!forcedRGB) {
+            forcedRGB = true;
+            int size = width*height;
+            int rgbData[] = new int[size];
+
+            if (bData != null) {
+                for (int i=0; i<size; i++) {
+                    rgbData[i] = cm.getRGB(bData[i]);
+                }
+            } else if (iData != null) {
+                for (int i=0; i<size; i++) {
+                    rgbData[i] = cm.getRGB(iData[i]);
+                }
+            }
+
+            cm = ColorModel.getRGBdefault();
+            DataBufferInt db = new DataBufferInt(rgbData, size);
+            int masks[] = new int[] {0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000};
+            raster = Raster.createPackedRaster(db, width, height, width, masks, null);
+            iData = accessor.getDataInt(db);
+            bData = null;
+            transferType = DataBuffer.TYPE_INT;
+        }
+    }
+
+    /**
+     * Reset.
+     */
+    private void reset() {
+        width = 0;
+        height = 0;
+        forcedRGB = false;
+        cm = null;
+        iData = null;
+        bData = null;
+        transferType = DataBuffer.TYPE_UNDEFINED;
+        raster = null;
+    }
+
+    /**
+     * Creates the raster.
+     * 
+     * @param dataType the data type
+     */
+    private void createRaster(int dataType) {
+        boolean createdValidBuffer = false;
+        try{
+            raster = cm.createCompatibleWritableRaster(width, height);
+            int rasterType = raster.getDataBuffer().getDataType();
+            if (rasterType == dataType) {
+                switch (rasterType) {
+                    case DataBuffer.TYPE_INT: {
+                        iData = accessor.getDataInt(raster.getDataBuffer());
+                        if (iData != null) {
+                            createdValidBuffer = true;
+                        }
+                        break;
+                    }
+                    case DataBuffer.TYPE_BYTE: {
+                        bData = accessor.getDataByte(raster.getDataBuffer());
+                        if (bData != null) {
+                            createdValidBuffer = true;
+                        }
+                        break;
+                    }
+                    default:
+                        createdValidBuffer = false;
+                }
+
+                if(cm == ColorModel.getRGBdefault()){
+                    forcedRGB = true;
+                }
+            } else {
+                createdValidBuffer = false;
+            }
+        } catch(Exception e) {
+            createdValidBuffer = false;
+        }
+
+        if (createdValidBuffer == false) {
+            cm = ColorModel.getRGBdefault();
+            raster = cm.createCompatibleWritableRaster(width, height);
+            iData = accessor.getDataInt(raster.getDataBuffer());
+            bData = null;
+            forcedRGB = true;
+        }
+    }
+}
diff --git a/awt/java/awt/image/BufferedImageOp.java b/awt/java/awt/image/BufferedImageOp.java
new file mode 100644
index 0000000..85b9f4e
--- /dev/null
+++ b/awt/java/awt/image/BufferedImageOp.java
@@ -0,0 +1,86 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The BufferedImageOp interface provides methods for performing transformations
+ * from source data to destination data for BufferedImage objects. An object
+ * implementing this interface can be passed into a BufferedImageFilter 
+ * to operate on a BufferedImage.
+ */
+public interface BufferedImageOp {
+    
+    /**
+     * Creates a destination image with the specified BufferedImage and
+     * ColorModel; this destination image is empty and has the correct size 
+     * and number of bands.   
+     * 
+     * @param src the source BufferedImage.
+     * @param destCM the destination ColorModel.
+     * 
+     * @return the BufferedImage.
+     */
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM);
+
+    /**
+     * Performs a filter operation on the source BufferedImage and stores 
+     * the resulting BufferedImage to the destination BufferedImage. If 
+     * the destination BufferedImage is null, a BufferedImage with an 
+     * appropriate ColorModel is created.
+     * 
+     * @param src the source BufferedImage.
+     * @param dest the destination BufferedImage, where the result is stored.
+     * 
+     * @return the filtered BufferedImage.
+     */
+    public BufferedImage filter(BufferedImage src, BufferedImage dest);
+
+    /**
+     * Gets the bounds of filtered image.
+     * 
+     * @param src the source BufferedImage to be filtered.
+     * 
+     * @return the rectangle bounds of filtered image.
+     */
+    public Rectangle2D getBounds2D(BufferedImage src);
+
+    /**
+     * Gets the point of the destination image which corresponds
+     * to the specified point in the source image. 
+     * 
+     * @param srcPt the point of the source image.
+     * @param dstPt the point where the result will be stored.
+     * 
+     * @return the destination point.
+     */
+    public Point2D getPoint2D(Point2D srcPt, Point2D dstPt);
+
+    /**
+     * Gets the RenderingHints of the BufferedImageOp.
+     * 
+     * @return the RenderingHints of the BufferedImageOp.
+     */
+    public RenderingHints getRenderingHints();
+}
diff --git a/awt/java/awt/image/ByteLookupTable.java b/awt/java/awt/image/ByteLookupTable.java
new file mode 100644
index 0000000..043b533
--- /dev/null
+++ b/awt/java/awt/image/ByteLookupTable.java
@@ -0,0 +1,134 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+/**
+ * The ByteLookupTable class provides functionality for lookup operations, 
+ * and is defined by an input byte array for bands or components of 
+ * image and an offset value.
+ * The offset value will be subtracted from the input values before 
+ * indexing the input arrays. The output of a lookup operation is 
+ * represented as an array of unsigned bytes.
+ */
+public class ByteLookupTable extends LookupTable {
+    
+    /** The data. */
+    private byte data[][];
+    
+    /**
+     * Instantiates a new ByteLookupTable with the specified offset value
+     * and the specified byte array which represents the lookup table for
+     * all bands.
+     * 
+     * @param offset the offset value.
+     * @param data the data array of bytes.
+     */
+    public ByteLookupTable(int offset, byte[] data) {
+        super(offset, 1);
+        if (data.length < 1)
+            throw new IllegalArgumentException("Length of data should not be less then one");
+        this.data = new byte[1][data.length];
+        // The data array stored as a reference
+        this.data[0] = data;
+    }
+
+    /**
+     * Instantiates a new ByteLookupTable with the specified offset value
+     * and the specified byte array of arrays which represents the lookup table
+     * for each band.
+     * 
+     * @param offset the offset value.
+     * @param data the data array of bytes array for each band.
+     */
+    public ByteLookupTable(int offset, byte[][] data) {
+        super(offset, data.length);
+        this.data = new byte[data.length][data[0].length];
+        for (int i = 0; i < data.length; i++) {
+            // The data array for each band stored as a reference
+            this.data[i] = data[i];
+        }
+    }
+
+    /**
+     * Gets the lookup table of this ByteLookupTable object. If 
+     * this ByteLookupTable object has one byte array for all bands, 
+     * the returned array length is one.
+     * 
+     * @return the lookup table of this ByteLookupTable object.
+     */
+    public final byte[][] getTable() {
+        // Returns data by reference
+        return data;
+    }
+
+    @Override
+    public int[] lookupPixel(int[] src, int[] dst) {
+        if (dst == null) {
+            dst = new int[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+
+    /**
+     * Returns a byte array which contains samples of the specified
+     * pixel which is translated with the lookup table of this 
+     * ByteLookupTable object. The resulted array is stored to
+     * the dst array.
+     * 
+     * @param src the source array.
+     * @param dst the destination array where the result can be stored.
+     * 
+     * @return the byte array of translated samples of a pixel.
+     */
+    public byte[] lookupPixel(byte[] src, byte[] dst) {
+        if (dst == null) {
+            dst = new byte[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+}
diff --git a/awt/java/awt/image/ColorConvertOp.java b/awt/java/awt/image/ColorConvertOp.java
new file mode 100644
index 0000000..6d503d7
--- /dev/null
+++ b/awt/java/awt/image/ColorConvertOp.java
@@ -0,0 +1,711 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */  
+package java.awt.image;
+
+
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+
+import org.apache.harmony.awt.gl.color.ColorConverter;
+import org.apache.harmony.awt.gl.color.ColorScaler;
+import org.apache.harmony.awt.gl.color.ICC_Transform;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ColorConvertOp class converts the pixels of the data in the
+ * source image with the specified ColorSpace objects or an array 
+ * of ICC_Profile objects. The result pixels are scaled to the precision
+ * of the destination image.
+ */
+public class ColorConvertOp implements BufferedImageOp, RasterOp {
+    // Unused but required by interfaces
+    /** The rendering hints. */
+    RenderingHints renderingHints;
+        
+    // Sequence consisting of ColorSpace and ICC_Profile elements
+    /** The conversion sequence. */
+    Object conversionSequence[] = new ICC_Profile[0]; // To eliminate checks for null
+    
+    // Not null if ColorConvertOp is constructed from the array of ICC profiles
+    /** The mid profiles. */
+    private ICC_Profile midProfiles[];   
+
+    /** The cc. */
+    private final ColorConverter cc = new ColorConverter();
+    
+    /** The t creator. */
+    private final ICC_TransfomCreator tCreator = new ICC_TransfomCreator();
+    
+    /** The is icc. */
+    private boolean isICC = true;
+    
+    
+    // Cached ICC_Transform
+    /**
+     * The Class ICC_TransfomCreator.
+     */
+    private class ICC_TransfomCreator {
+        
+        /** The transform. */
+        private ICC_Transform transform;
+        
+        /** The max components. */
+        private int maxComponents;
+        
+        /**
+         * For the full ICC case.
+         * 
+         * @param src the src
+         * @param dst the dst
+         * @param convSeq the conv seq
+         * 
+         * @return the transform
+         */
+        public ICC_Transform getTransform(ICC_Profile src, ICC_Profile dst, ICC_Profile convSeq[]) {
+            if (transform != null &&
+               src == transform.getSrc() && 
+               dst == transform.getDst()) {
+                return transform;
+            }
+            
+            int length = convSeq.length;
+            int srcFlg = 0, dstFlg = 0;
+            
+            if (length == 0 || src != convSeq[0]) {
+                if (src != null) {
+                    srcFlg = 1; // need src profile
+                }
+            }
+            if (length == 0 || dst != convSeq[length-1]) {
+                if (dst != null) {
+                    dstFlg = 1; // need dst profile
+                }
+            }
+            
+            ICC_Profile profiles[];
+            int nProfiles = length + srcFlg + dstFlg;
+            if (nProfiles == length) {
+                profiles = convSeq;
+            } else {
+                profiles = new ICC_Profile[nProfiles];
+                int pos = 0;
+                if (srcFlg != 0) {
+                    profiles[pos++] = src;
+                }
+                for (int i=0; i<length; i++) {
+                    profiles[pos++] = convSeq[i];
+                }
+                if (dstFlg != 0) {
+                    profiles[pos++] = dst;
+                }
+            }
+            
+            return transform = new ICC_Transform(profiles);
+        }
+        
+        /**
+         * Used only when there are non-ICC color spaces.
+         * Returns sequence of non-ICC color spaces and ICC transforms
+         * made from src, dst and conversionSequence.
+         * 
+         * @param src the src
+         * @param dst the dst
+         * 
+         * @return the sequence
+         */
+        public Object[] getSequence(Object src, Object dst) {
+            ArrayList<Object> profiles = new ArrayList<Object>(10);
+            ArrayList<Object> sequence = new ArrayList<Object>(10);         
+
+            // We need this profile anyway
+            ICC_Profile xyzProfile = ICC_Profile.getInstance(ColorSpace.CS_CIEXYZ);
+
+            Object conversionFirst = null, conversionLast = null;
+            int conversionLength = conversionSequence.length;
+            if (conversionLength > 0) {
+                conversionFirst = conversionSequence[0];
+                conversionLast = conversionSequence[conversionLength-1];
+            }
+
+            boolean iccSequenceStarted = false;
+            
+            if (src != conversionFirst && src != null) {
+                if (src instanceof ICC_Profile) {
+                    profiles.add(src);
+                    iccSequenceStarted = true;
+                } else {
+                    profiles.add(xyzProfile);
+                    sequence.add(src); // Add non-ICC color space to the sequence
+                } 
+            } else {
+                profiles.add(xyzProfile);
+            }
+            
+            for (int i=0; i<conversionLength; i++) {
+                if (conversionSequence[i] instanceof ICC_Profile) {
+                    profiles.add(conversionSequence[i]);
+                    iccSequenceStarted = true;
+                } else if (iccSequenceStarted) {
+                    profiles.add(xyzProfile);
+                    
+                    // Eliminate same profiles if there are any
+                    // (e.g. xyzProfile may occur several times)
+                    Object prev = profiles.get(0);
+                    for (int k=1; k<profiles.size(); k++) {                     
+                        if (prev == profiles.get(k)) {
+                            k--;
+                            profiles.remove(k);
+                        }
+                        prev = profiles.get(k);
+                    }
+                    
+                    // If only one profile left we skip the transform -
+                    // it can be only CIEXYZ
+                    if (profiles.size() > 1) {
+                        sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
+
+                        // Add non-ICC color space to the sequence
+                        sequence.add(conversionSequence[i]);
+                    }
+                    
+                    profiles.clear();
+                    profiles.add(xyzProfile);
+                    iccSequenceStarted = false; // Sequence of ICC profiles is processed
+                } else { // Add non-ICC color space to the sequence
+                    sequence.add(conversionSequence[i]); 
+                }               
+            }
+            
+            if (dst != conversionLast && dst != null) { // Add last profile if needed
+                if (dst instanceof ICC_Profile) {
+                    profiles.add(dst);
+                    iccSequenceStarted = true;
+                } else if (iccSequenceStarted) {
+                    profiles.add(xyzProfile);
+                } else {
+                    sequence.add(dst); // Add last non-ICC color space to the sequence
+                }
+            }
+            
+            if (iccSequenceStarted) { // Make last transform if needed
+                sequence.add(new ICC_Transform(profiles.toArray(new ICC_Profile[0])));
+                if (dst != null && !(dst instanceof ICC_Profile)) {
+                    sequence.add(dst); // Add last non-ICC color space to the
+                                        // sequence
+                }
+            }
+
+            // Calculate max number of components
+            // This number will be used for memory allocation
+            maxComponents = 0;
+            Object o;           
+            for (int i=0, size = sequence.size(); i<size; i++) {
+                o = sequence.get(i);
+                if (o instanceof ICC_Transform) {
+                    ICC_Transform t = (ICC_Transform) o; 
+                    maxComponents = 
+                        (maxComponents > t.getNumInputChannels() + 1) ?
+                            maxComponents : 
+                            t.getNumInputChannels() + 1;
+                    maxComponents = 
+                        (maxComponents > t.getNumOutputChannels() + 1) ?
+                            maxComponents : 
+                            t.getNumOutputChannels() + 1;
+                } else {
+                    ColorSpace cs = (ColorSpace) o;
+                    maxComponents = 
+                        (maxComponents > cs.getNumComponents() + 1) ?
+                            maxComponents : 
+                            cs.getNumComponents() + 1;
+                }               
+            }
+            
+            return sequence.toArray();
+        }
+    }
+    
+    /**
+     * Instantiates a new ColorConvertOp object using two specified
+     * ColorSpace objects.
+     * 
+     * @param srcCS the source ColorSpace.
+     * @param dstCS the destination ColorSpace.
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(ColorSpace srcCS, ColorSpace dstCS, RenderingHints hints) {
+        if (srcCS == null || dstCS == null) {
+            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
+        }
+        
+        renderingHints = hints;
+        
+        boolean srcICC = srcCS instanceof ICC_ColorSpace;
+        boolean dstICC = dstCS instanceof ICC_ColorSpace;
+        
+        if (srcICC && dstICC) {
+            conversionSequence = new ICC_Profile[2];
+        } else {
+            conversionSequence = new Object[2];
+            isICC = false;
+        }
+        
+        if (srcICC) {
+            conversionSequence[0] = ((ICC_ColorSpace) srcCS).getProfile();
+        } else {
+            conversionSequence[0] = srcCS;
+        }
+        
+        if (dstICC) {
+            conversionSequence[1] = ((ICC_ColorSpace) dstCS).getProfile();
+        } else {
+            conversionSequence[1] = dstCS;
+        }
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object from the specified 
+     * ICC_Profile objects.
+     * 
+     * @param profiles the array of ICC_Profile objects.
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(ICC_Profile profiles[], RenderingHints hints) {
+        if (profiles == null) {
+            throw new NullPointerException(Messages.getString("awt.25C")); //$NON-NLS-1$
+        }
+
+        renderingHints = hints;
+        
+        // This array is not used in the program logic, so don't need to copy it
+        // Store it only to return back
+        midProfiles = profiles;  
+        
+        conversionSequence = new ICC_Profile[midProfiles.length];
+        
+        // Add profiles to the conversion sequence
+        for (int i=0, length=midProfiles.length; i<length; i++) {
+            conversionSequence[i] = midProfiles[i];
+        }       
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object using the specified
+     * ColorSpace object.
+     * 
+     * @param cs the destination ColorSpace or an intermediate ColorSpace.
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(ColorSpace cs, RenderingHints hints) {
+        if (cs == null) {
+            throw new NullPointerException(Messages.getString("awt.25B")); //$NON-NLS-1$
+        }
+        
+        renderingHints = hints;
+                        
+        if (cs instanceof ICC_ColorSpace) {
+            conversionSequence = new ICC_Profile[1];
+            conversionSequence[0] = ((ICC_ColorSpace) cs).getProfile();
+        } else {
+            conversionSequence = new Object[1];
+            conversionSequence[0] = cs;
+            isICC = false;
+        }
+    }
+
+    /**
+     * Instantiates a new ColorConvertOp object which converts from 
+     * a source color space to a destination color space.
+     * 
+     * @param hints the RenderingHints object used for 
+     * the color conversion, or null.
+     */
+    public ColorConvertOp(RenderingHints hints) {
+        renderingHints = hints;
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (conversionSequence.length < 2) {
+            throw new IllegalArgumentException(Messages.getString("awt.25D")); //$NON-NLS-1$
+        }
+
+        ICC_Profile srcPf = null, dstPf = null; // unused if isICC is false
+        int nSrcColorComps, nDstColorComps;
+        Object first = conversionSequence[0];
+        Object last = conversionSequence[conversionSequence.length - 1];
+        
+        // Get the number of input/output color components
+        if (isICC) {
+            srcPf = (ICC_Profile) first;
+            dstPf = (ICC_Profile) last;
+            nSrcColorComps = srcPf.getNumComponents();
+            nDstColorComps = dstPf.getNumComponents();
+        } else {
+            if (first instanceof ICC_Profile) {
+                srcPf = (ICC_Profile) first;
+                nSrcColorComps = srcPf.getNumComponents();
+            } else {
+                nSrcColorComps = ((ColorSpace) first).getNumComponents();
+            }
+            
+            if (last instanceof ICC_Profile) {
+                dstPf = (ICC_Profile) last;
+                nDstColorComps = dstPf.getNumComponents();
+            } else {
+                nDstColorComps = ((ColorSpace) last).getNumComponents();
+            }
+        }
+
+        // Check that source and destination rasters are compatible with
+        // transforms and with each other
+        if (src.getNumBands() != nSrcColorComps) {
+            // awt.25E=Incorrect number of source raster bands. Should be equal
+            //          to the number of color components of source colorspace.
+            throw new IllegalArgumentException(Messages.getString("awt.25E")); //$NON-NLS-1$
+        }
+        
+        if (dst != null) { // Check destination raster
+            if (dst.getNumBands() !=
+                nDstColorComps) {
+                // awt.25F=Incorrect number of destination raster bands. Should
+                //          be equal to the number of color components of destination
+                //          colorspace.
+                throw new IllegalArgumentException(Messages.getString("awt.25F")); //$NON-NLS-1$
+            }
+            
+            if (src.getWidth() != dst.getWidth() ||
+               src.getHeight() != dst.getHeight()) {
+                throw new IllegalArgumentException(Messages.getString("awt.260")); //$NON-NLS-1$
+            }
+            
+        } else {
+          dst = createCompatibleDestRaster(src);
+        }
+        
+        if (isICC) {
+            // Create transform
+            ICC_Transform t = tCreator.getTransform(srcPf, dstPf, 
+                    (ICC_Profile[])conversionSequence); 
+            cc.translateColor(t, src, dst);         
+        } else {
+            Object[] sequence = tCreator.getSequence(null, null);
+            
+            // Get data from the source raster
+            ColorScaler scaler = new ColorScaler();
+            scaler.loadScalingData(src, null);
+            float tmpData[][] = scaler.scaleNormalize(src);
+            
+            // Get source and destination color spaces
+            ColorSpace srcCS = (srcPf == null) ? 
+                    (ColorSpace) first:
+                    new ICC_ColorSpace(srcPf);
+            ColorSpace dstCS = (dstPf == null) ? 
+                    (ColorSpace) last:
+                    new ICC_ColorSpace(dstPf);
+                    
+            applySequence(sequence, tmpData, srcCS, dstCS);
+            
+            scaler.loadScalingData(dst, null);
+            scaler.unscaleNormalized(dst, tmpData);
+        }
+
+        return dst;
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
+        // If destination color model is passed only one line needed
+        if (destCM != null) {
+            return new BufferedImage(destCM,
+                    destCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()),
+                    destCM.isAlphaPremultiplied(), 
+                    null);
+        }
+        
+        int nSpaces = conversionSequence.length;
+        
+        if (nSpaces < 1) {
+            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
+        }
+        
+        // Get destination color space
+        Object destination = conversionSequence[nSpaces-1];
+        ColorSpace dstCS = 
+            (destination instanceof ColorSpace) ? 
+                    (ColorSpace) destination : 
+                    new ICC_ColorSpace((ICC_Profile) destination);
+        
+        ColorModel srcCM = src.getColorModel();     
+        ColorModel dstCM = new ComponentColorModel(dstCS, 
+                srcCM.hasAlpha(), 
+                srcCM.isAlphaPremultiplied(),
+                srcCM.getTransparency(),
+                srcCM.getTransferType());
+        
+        return new BufferedImage(dstCM,
+                destCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()),
+                destCM.isAlphaPremultiplied(), 
+                null);
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (dst == null && conversionSequence.length < 1) {
+            throw new IllegalArgumentException(Messages.getString("awt.262")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        // First handle index color model
+        if (srcCM instanceof IndexColorModel) {            
+            src = ((IndexColorModel) srcCM).convertToIntDiscrete(src.getRaster(), false);
+        }
+        ColorSpace srcCS = srcCM.getColorSpace();        
+                
+        BufferedImage res;
+        boolean isDstIndex = false;
+        if (dst != null) {
+          
+          if (src.getWidth() != dst.getWidth() ||
+             src.getHeight() != dst.getHeight()) {
+              throw new IllegalArgumentException(Messages.getString("awt.263")); //$NON-NLS-1$
+          }
+
+            if (dst.getColorModel() instanceof IndexColorModel) {
+                isDstIndex = true;
+                res = createCompatibleDestImage(src, null);
+            } else {                
+                res = dst;
+            }           
+        } else {
+            res = createCompatibleDestImage(src, null);
+        }
+        ColorModel dstCM = res.getColorModel();
+        ColorSpace dstCS = dstCM.getColorSpace();
+        
+        ICC_Profile srcPf = null, dstPf = null;
+        if (srcCS instanceof ICC_ColorSpace) {
+            srcPf = ((ICC_ColorSpace)srcCS).getProfile();
+        }
+        if (dstCS instanceof ICC_ColorSpace) {
+            dstPf = ((ICC_ColorSpace)dstCS).getProfile();
+        }
+        
+        boolean isFullICC = isICC && srcPf != null && dstPf != null;
+        
+        if (isFullICC) {
+            ICC_Transform t =
+                    tCreator.getTransform(srcPf, dstPf, (ICC_Profile[]) conversionSequence);
+            cc.translateColor(t, src, res);
+        } else { // Perform non-ICC transform
+            Object sequence[] = tCreator.getSequence(
+                    srcPf == null ? (Object) srcCS : srcPf,
+                    dstPf == null ? (Object) dstCS : dstPf);            
+            
+            int srcW = src.getWidth();
+            int srcH = src.getHeight();
+            int numPixels = srcW*srcH;
+
+            // Load all pixel data into array tmpData 
+            float tmpData[][] = 
+                new float[numPixels][tCreator.maxComponents];
+            for (int row=0, dataPos=0; row<srcW; row++) {
+                for (int col=0; col<srcH; col++) {
+                    tmpData[dataPos] = 
+                        srcCM.getNormalizedComponents(
+                                src.getRaster().getDataElements(row, col, null), 
+                                tmpData[dataPos], 0);
+                    dataPos++;
+                }
+            }
+
+            // Copy alpha channel if needed
+            float alpha[] = null;
+            int alphaIdx = srcCM.numComponents - 1;
+            if (srcCM.hasAlpha() && dstCM.hasAlpha()) {
+                alpha = new float[numPixels];
+                for (int i=0; i<numPixels; i++) {
+                    alpha[i] = tmpData[i][alphaIdx];
+                }
+            }
+            
+            // Translate colors
+            applySequence(sequence, tmpData, srcCS, dstCS);
+
+            // Copy alpha if needed
+            if (dstCM.hasAlpha()) {
+                alphaIdx = dstCM.numComponents - 1;
+                if (alpha != null) {
+                    for (int i=0; i<numPixels; i++) {
+                        tmpData[i][alphaIdx] = alpha[i];
+                    }                   
+                } else {
+                    for (int i=0; i<numPixels; i++) {
+                        tmpData[i][alphaIdx] = 1f;
+                    }                                       
+                }
+            }
+            
+            // Store data back to the image            
+            for (int row=0, dataPos=0; row<srcW; row++) {
+                for (int col=0; col<srcH; col++) {
+                    res.getRaster().setDataElements(row, col, 
+                            dstCM.getDataElements(tmpData[dataPos++], 0 , null));
+                }
+            }
+        }               
+
+        if (isDstIndex) { // Convert image into indexed color
+            Graphics2D g2d = dst.createGraphics();
+            g2d.drawImage(res, 0, 0, null);
+            g2d.dispose();
+            return dst;
+        }
+        
+        return res;
+    }
+
+    /**
+     * Apply sequence.
+     * 
+     * @param sequence the sequence
+     * @param tmpData the tmp data
+     * @param srcCS the src cs
+     * @param dstCS the dst cs
+     */
+    private void applySequence(
+            Object sequence[], 
+            float tmpData[][],
+            ColorSpace srcCS, 
+            ColorSpace dstCS
+            ) {
+        ColorSpace xyzCS = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
+        
+        int numPixels = tmpData.length;
+        
+        // First transform...
+        if (sequence[0] instanceof ICC_Transform) { // ICC
+            ICC_Transform t = (ICC_Transform)sequence[0];
+            cc.translateColor(t, tmpData, srcCS, xyzCS, numPixels);
+        } else { // non ICC
+            for (int k=0; k<numPixels; k++) {
+                tmpData[k] = srcCS.toCIEXYZ(tmpData[k]); 
+            }
+            cc.loadScalingData(xyzCS); // prepare for scaling XYZ
+        }
+        
+        for (Object element : sequence) {
+            if (element instanceof ICC_Transform) {
+                ICC_Transform t = (ICC_Transform)element;
+                cc.translateColor(t, tmpData, null, null, numPixels);
+            } else {
+                ColorSpace cs = (ColorSpace) element;
+                for (int k=0; k<numPixels; k++) {
+                    tmpData[k] = cs.fromCIEXYZ(tmpData[k]);
+                    tmpData[k] = cs.toCIEXYZ(tmpData[k]); 
+                }
+            }
+        }
+        
+        // Last transform...
+        if (sequence[sequence.length-1] instanceof ICC_Transform) { // ICC
+            ICC_Transform t = (ICC_Transform)sequence[sequence.length-1];
+            cc.translateColor(t, tmpData, xyzCS, dstCS, numPixels);
+        } else { // non ICC
+            for (int k=0; k<numPixels; k++) {
+                tmpData[k] = dstCS.fromCIEXYZ(tmpData[k]); 
+            }
+        }
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt != null) {
+            dstPt.setLocation(srcPt);
+            return dstPt;
+        }
+        return new Point2D.Float((float) srcPt.getX(), (float) srcPt.getY());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        int nComps = 0;
+        int nSpaces = conversionSequence.length;
+        
+        if (nSpaces < 2) {
+            throw new IllegalArgumentException(Messages.getString("awt.261")); //$NON-NLS-1$
+        }
+        
+        Object lastCS = conversionSequence[nSpaces-1];
+        if (lastCS instanceof ColorSpace) {
+            nComps = ((ColorSpace) lastCS).getNumComponents();
+        } else {
+            nComps = ((ICC_Profile) lastCS).getNumComponents(); 
+        }
+        
+        // Calculate correct data type
+        int dstDataType = src.getDataBuffer().getDataType();
+        if (dstDataType != DataBuffer.TYPE_BYTE &&
+           dstDataType != DataBuffer.TYPE_SHORT) {
+                dstDataType = DataBuffer.TYPE_SHORT;
+        }
+        
+        return Raster.createInterleavedRaster(
+                dstDataType, 
+                src.getWidth(),
+                src.getHeight(),
+                nComps,
+                new Point(src.getMinX(), src.getMinY())
+            );
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return src.getRaster().getBounds();
+    }
+
+    /**
+     * Gets an array of ICC_Profiles objects which constructs
+     * this ColorConvertOp object or returns null if this ColorConvertOp 
+     * is not constructed from array of ICC_Profiles.
+     * 
+     * @return an array of ICC_Profiles objects which constructs
+     * this ColorConvertOp object or returns null if this ColorConvertOp 
+     * is not constructed from array of ICC_Profiles.
+     */
+    public final ICC_Profile[] getICC_Profiles() {
+        if (midProfiles != null) {
+            return midProfiles;
+        }
+        return null;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return renderingHints;
+    }    
+}
diff --git a/awt/java/awt/image/ColorModel.java b/awt/java/awt/image/ColorModel.java
new file mode 100644
index 0000000..945c087
--- /dev/null
+++ b/awt/java/awt/image/ColorModel.java
@@ -0,0 +1,911 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class ColorModel.
+ */
+public abstract class ColorModel implements Transparency {
+
+    /** The pixel_bits. */
+    protected int pixel_bits;  // Pixel length in bits
+
+    /** The transfer type. */
+    protected int transferType;
+
+    /** The cs. */
+    ColorSpace cs;
+
+    /** The has alpha. */
+    boolean hasAlpha;
+
+    /** The is alpha premultiplied. */
+    boolean isAlphaPremultiplied;
+
+    /** The transparency. */
+    int transparency;
+
+    /** The num color components. */
+    int numColorComponents;
+
+    /** The num components. */
+    int numComponents;
+
+    /** The bits. */
+    int[] bits;             // Array of components masks 
+
+    /** The max values. */
+    int[] maxValues = null; // Max values that may be represent by color
+                            // components
+
+    /** The max bit length. */
+    int maxBitLength;       // Max length color components in bits
+
+    /** The RG bdefault. */
+    private static ColorModel RGBdefault;
+
+    /**
+     * Instantiates a new color model with the specified values.
+     * 
+     * @param pixel_bits the pixel length in bits
+     * @param bits the array of component masks
+     * @param cspace the colorspace
+     * @param hasAlpha whether the color model has alpha
+     * @param isAlphaPremultiplied whether the alpha is premultiplied
+     * @param transparency the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     */
+    protected ColorModel(int pixel_bits, int[] bits, ColorSpace cspace,
+            boolean hasAlpha, boolean isAlphaPremultiplied, int transparency,
+            int transferType) {
+
+        if (pixel_bits < 1) {
+            // awt.26B=The number of bits in the pixel values is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.26B")); //$NON-NLS-1$
+        }
+
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new NullPointerException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        int sum = 0;
+        for (int element : bits) {
+            if (element < 0) {
+                // awt.26D=The elements in bits is less than 0
+                throw new IllegalArgumentException(Messages.getString("awt.26D")); //$NON-NLS-1$
+            }
+            sum += element;
+        }
+
+        if (sum < 1) {
+            // awt.26E=The sum of the number of bits in bits is less than 1
+            throw new NullPointerException(Messages.getString("awt.26E")); //$NON-NLS-1$
+        }
+
+        if (cspace == null) {
+            // awt.26F=The cspace is null
+            throw new IllegalArgumentException(Messages.getString("awt.26F")); //$NON-NLS-1$
+        }
+
+        if (transparency < Transparency.OPAQUE ||
+               transparency > Transparency.TRANSLUCENT) {
+            // awt.270=The transparency is not a valid value
+            throw new IllegalArgumentException(Messages.getString("awt.270")); //$NON-NLS-1$
+        }
+
+        this.pixel_bits = pixel_bits;
+        this.bits = bits.clone();
+
+        maxValues = new int[bits.length];
+        maxBitLength = 0;
+        for (int i = 0; i < maxValues.length; i++) {
+            maxValues[i] = (1 << bits[i]) - 1;
+            if (bits[i] > maxBitLength) {
+                maxBitLength = bits[i];
+            }
+        }
+
+        cs = cspace;
+        this.hasAlpha = hasAlpha;
+        this.isAlphaPremultiplied = isAlphaPremultiplied;
+        numColorComponents = cs.getNumComponents();
+
+        if (hasAlpha) {
+            numComponents = numColorComponents + 1;
+        } else {
+            numComponents = numColorComponents;
+        }
+
+        this.transparency = transparency;
+        this.transferType = transferType;
+
+    }
+
+    /**
+     * Instantiates a new color model with the specified pixel bit depth.
+     * The transferType is chosen based on the pixel bits, and the other
+     * data fields are given default values.
+     * 
+     * @param bits the array of component masks
+     */
+    public ColorModel(int bits) {
+
+        if (bits < 1) {
+            // awt.271=The number of bits in bits is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.271")); //$NON-NLS-1$
+        }
+
+        pixel_bits = bits;
+        transferType = getTransferType(bits);
+        cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        hasAlpha = true;
+        isAlphaPremultiplied = false;
+        transparency = Transparency.TRANSLUCENT;
+
+        numColorComponents = 3;
+        numComponents = 4;
+
+        this.bits = null;
+    }
+
+    /**
+     * Gets the data elements from the specified component array, transforming
+     * them according to rules of the color model.
+     * 
+     * @param components the components
+     * @param offset the offset in the normComponents array
+     * @param obj the array that the result is written to: an array of values
+     * whose length must be the number of components used by the color model and 
+     * whose type depends on the transfer type (based on the pixel bit depth),
+     * or null to have the appropriate array created
+     * 
+     * @return the array of data elements
+     */
+    public Object getDataElements(int[] components, int offset, Object obj) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the data elements from the specified array of normalized components.
+     * 
+     * @param normComponents the array normalized components
+     * @param normOffset the offset in the normComponents array
+     * @param obj the array that the result is written to: an array of values
+     * whose length must be the number of components used by the color model and 
+     * whose type depends on the transfer type (based on the pixel bit depth),
+     * or null to have the appropriate array created
+     * 
+     * @return the array of data elements
+     */
+    public Object getDataElements(float[] normComponents, int normOffset,
+            Object obj) {
+        int unnormComponents[] = getUnnormalizedComponents(normComponents,
+                normOffset, null, 0);
+        return getDataElements(unnormComponents, 0, obj);
+    }
+
+    /**
+     * Gets the data elements corresponding to the pixel determined by the 
+     * RGB data.
+     * 
+     * @param rgb the rgb int that defines the pixel
+     * @param pixel the array that the result is written to: an array of values
+     * whose length must be the number of components used by the color model and 
+     * whose type depends on the transfer type (based on the pixel bit depth),
+     * or null to have the appropriate array created
+     * 
+     * @return the array of data elements
+     */
+    public Object getDataElements(int rgb, Object pixel) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the child raster corresponding to the alpha channel of the 
+     * specified writable raster, or null if alpha is not supported.
+     * 
+     * @param raster the raster
+     * 
+     * @return the alpha raster
+     */
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        return null;
+    }
+
+    /**
+     * Creates a new color model by coercing the data in the writable raster 
+     * in accordance with the alpha strategy of this color model.
+     * 
+     * @param raster the raster
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this 
+     * color model
+     * 
+     * @return the new color model
+     */
+    public ColorModel coerceData(WritableRaster raster,
+            boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. 
+        // It could be reveled such way:
+        // ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB,
+        // false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+        // System.out.println(cm.toString());
+        return "ColorModel: Color Space = " + cs.toString() + "; has alpha = " //$NON-NLS-1$ //$NON-NLS-2$
+                + hasAlpha + "; is alpha premultipied = " //$NON-NLS-1$
+                + isAlphaPremultiplied + "; transparency = " + transparency //$NON-NLS-1$
+                + "; number color components = " + numColorComponents //$NON-NLS-1$
+                + "; pixel bits = " + pixel_bits + "; transfer type = " //$NON-NLS-1$ //$NON-NLS-2$
+                + transferType;
+    }
+
+    /**
+     * Gets the components of the pixel determined by the data array.
+     * 
+     * @param pixel the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * @param components the the array where the resulting components
+     * are written (or null to prompt the method to create the return array)
+     * @param offset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the array of components
+     */
+    public int[] getComponents(Object pixel, int[] components, int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the normalized components of the pixel determined by the data array.
+     * 
+     * @param pixel the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * @param normComponents the array where the resulting normalised components
+     * are written (or null to prompt the method to create the return array)
+     * @param normOffset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the array of normalized components
+     */
+    public float[] getNormalizedComponents(Object pixel,
+            float[] normComponents, int normOffset) {
+
+        if (pixel == null) {
+            // awt.294=pixel is null
+            throw new NullPointerException(Messages.getString("awt.294")); //$NON-NLS-1$
+        }
+
+        int unnormComponents[] = getComponents(pixel, null, 0);
+        return getNormalizedComponents(unnormComponents, 0, normComponents,
+                normOffset);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ColorModel)) {
+            return false;
+        }
+        ColorModel cm = (ColorModel) obj;
+
+        return (pixel_bits == cm.getPixelSize() &&
+               transferType == cm.getTransferType() &&
+               cs.getType() == cm.getColorSpace().getType() &&
+               hasAlpha == cm.hasAlpha() &&
+               isAlphaPremultiplied == cm.isAlphaPremultiplied() &&
+               transparency == cm.getTransparency() &&
+               numColorComponents == cm.getNumColorComponents() &&
+               numComponents == cm.getNumComponents() &&
+               Arrays.equals(bits, cm.getComponentSize()));
+    }
+
+    /**
+     * Gets the red component of the pixel determined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the red
+     */
+    public int getRed(Object inData) {
+        return getRed(constructPixel(inData));
+    }
+
+    /**
+     * Gets the RGB int corresponding to the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the int that gives the pixel's colors in RGB format
+     */
+    public int getRGB(Object inData) {
+        return (getAlpha(inData) << 24 | getRed(inData) << 16 |
+               getGreen(inData) << 8 | getBlue(inData));
+    }
+
+    /**
+     * Gets the green component of the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the green
+     */
+    public int getGreen(Object inData) {
+        return getGreen(constructPixel(inData));
+    }
+
+    /**
+     * Gets the blue component of the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the blue
+     */
+    public int getBlue(Object inData) {
+        return getBlue(constructPixel(inData));
+    }
+
+    /**
+     * Gets the alpha component of the pixel defined by the data array.
+     * 
+     * @param inData the data array that defines the pixel (whose 
+     * primitive type corresponds to the pixel length in bits, 
+     * @see ColorModel#getTransferType()
+     * 
+     * @return the alpha
+     */
+    public int getAlpha(Object inData) {
+        return getAlpha(constructPixel(inData));
+    }
+
+    /**
+     * Creates a compatible writable raster.
+     * 
+     * @param w the width of the desired writable raster
+     * @param h the height of the desired writable raster
+     * 
+     * @return the writable raster
+     */
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if the sample model is compatible with this color model.
+     * 
+     * @param sm the sample model
+     * 
+     * @return true, if the sample model is compatible with this color model
+     */
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates the compatible sample model.
+     * 
+     * @param w the width of the desired sample model
+     * @param h the height of the desired sample model
+     * 
+     * @return the sample model
+     */
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Checks if the specified raster is compatible with this color model.
+     * 
+     * @param raster the raster to inspect
+     * 
+     * @return true, if the raster is compatible with this color model
+     */
+    public boolean isCompatibleRaster(Raster raster) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the color space of this color model.
+     * 
+     * @return the color space
+     */
+    public final ColorSpace getColorSpace() {
+        return cs;
+    }
+
+    /**
+     * Gets the normalized components corresponding to the specified 
+     * unnormalized components.
+     * 
+     * @param components the array of unnormalized components
+     * @param offset the offset where the components should be read 
+     * from the array of unnormalized components
+     * @param normComponents the array where the resulting normalised components
+     * are written (or null to prompt the method to create the return array)
+     * @param normOffset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the normalized components
+     */
+    public float[] getNormalizedComponents(int[] components, int offset,
+            float normComponents[], int normOffset) {
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new UnsupportedOperationException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (normComponents == null) {
+            normComponents = new float[numComponents + normOffset];
+        }
+
+        if (hasAlpha && isAlphaPremultiplied) {
+            float normAlpha =
+                (float) components[offset + numColorComponents] /
+                    maxValues[numColorComponents];
+            if (normAlpha != 0.0f) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComponents[normOffset + i] =
+                        components[offset + i] /
+                            (normAlpha * maxValues[i]);
+                }
+                normComponents[normOffset + numColorComponents] = normAlpha;
+            } else {
+                for (int i = 0; i < numComponents; i++) {
+                    normComponents[normOffset + i] = 0.0f;
+                }
+            }
+        } else {
+            for (int i = 0; i < numComponents; i++) {
+                normComponents[normOffset + i] =
+                    (float) components[offset + i] /
+                        maxValues[i];
+            }
+        }
+
+        return normComponents;
+    }
+
+    /**
+     * Gets the data element corresponding to the unnormalized components.
+     * 
+     * @param components the components
+     * @param offset the offset to start reading the components from the 
+     * array of components
+     * 
+     * @return the data element
+     */
+    public int getDataElement(int[] components, int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the unnormalized components corresponding to the specified 
+     * normalized components.
+     * 
+     * @param normComponents the array of normalized components
+     * @param normOffset the offset where the components should be read 
+     * from the array of normalized components
+     * @param components the array where the resulting unnormalised components
+     * are written (or null to prompt the method to create the return array)
+     * @param offset the offset that tells where the results should be written
+     * in the return array
+     * 
+     * @return the unnormalized components
+     */
+    public int[] getUnnormalizedComponents(float normComponents[],
+            int normOffset, int components[], int offset) {
+
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new UnsupportedOperationException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (normComponents.length - normOffset < numComponents) {
+            // awt.273=The length of normComponents minus normOffset is less than numComponents
+            throw new IllegalArgumentException(Messages.getString("awt.273")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[numComponents + offset];
+        } else {
+            if (components.length - offset < numComponents) {
+                // awt.272=The length of components minus offset is less than numComponents
+                throw new IllegalArgumentException(Messages.getString("awt.272")); //$NON-NLS-1$
+            }
+        }
+
+        if (hasAlpha && isAlphaPremultiplied) {
+            float alpha = normComponents[normOffset + numColorComponents];
+            for (int i = 0; i < numColorComponents; i++) {
+                components[offset + i] = (int) (normComponents[normOffset + i]
+                        * maxValues[i] * alpha + 0.5f);
+            }
+            components[offset + numColorComponents] =
+                (int) (normComponents[normOffset + numColorComponents] *
+                        maxValues[numColorComponents] + 0.5f);
+        } else {
+            for (int i = 0; i < numComponents; i++) {
+                components[offset + i] =
+                    (int) (normComponents[normOffset + i] *
+                            maxValues[i] + 0.5f);
+            }
+        }
+
+        return components;
+    }
+
+    /**
+     * Gets the data element corresponding to the normalized components.
+     * 
+     * @param normComponents the normalized components
+     * @param normOffset the offset where the normalized components should
+     * be read from the normalized component array
+     * 
+     * @return the data element
+     */
+    public int getDataElement(float normComponents[], int normOffset) {
+        int unnormComponents[] = getUnnormalizedComponents(normComponents,
+                normOffset, null, 0);
+        return getDataElement(unnormComponents, 0);
+    }
+
+    /**
+     * Takes a pixel whose data is defined by an int, and writes the 
+     * corresponding components into the components array, starting 
+     * from the index offset.
+     * 
+     * @param pixel the pixel data
+     * @param components the data array to write the components to (or
+     * null to have the method create the return array)
+     * @param offset the offset that determines where the results are 
+     * written in the components array
+     * 
+     * @return the array of components corresponding to the pixel
+     */
+    public int[] getComponents(int pixel, int components[], int offset) {
+        throw new UnsupportedOperationException("This method is not " + //$NON-NLS-1$
+                "supported by this ColorModel"); //$NON-NLS-1$
+    }
+
+    /**
+     * Gets the red component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel data
+     * 
+     * @return the red component of the pixel
+     */
+    public abstract int getRed(int pixel);
+
+    /**
+     * Takes the pixel data and returns the int corresponding 
+     * to the pixel's color in RGB format.
+     * 
+     * @param pixel the pixel data
+     * 
+     * @return the corresponding RGB int
+     */
+    public int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24 | getRed(pixel) << 16
+                | getGreen(pixel) << 8 | getBlue(pixel));
+    }
+
+    /**
+     * Gets the green component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel data
+     * 
+     * @return the green component of the pixel
+     */
+    public abstract int getGreen(int pixel);
+
+    /**
+     * Gets the size of the desired component of this color model.
+     * 
+     * @param componentIdx the index that determines which component size to get
+     * 
+     * @return the component size corresponding to the index
+     * 
+     * @throws NullPointerException if this color model doesn't support
+     * an array of separate components.
+     * @throws ArrayIndexOutOfBoundsException if the index is negative or
+     * greater than or equal to the number of components
+     */
+    public int getComponentSize(int componentIdx) {
+        if (bits == null) {
+            // awt.26C=bits is null
+            throw new NullPointerException(Messages.getString("awt.26C")); //$NON-NLS-1$
+        }
+
+        if (componentIdx < 0 || componentIdx >= bits.length) {
+            // awt.274=componentIdx is greater than the number of components or less than zero
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.274")); //$NON-NLS-1$
+        }
+
+        return bits[componentIdx];
+    }
+
+    /**
+     * Gets the blue component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel
+     * 
+     * @return the blue component of the pixel
+     */
+    public abstract int getBlue(int pixel);
+
+    /**
+     * Gets the alpha component of the pixel determined by the pixel data.
+     * 
+     * @param pixel the pixel
+     * 
+     * @return the alpha component of the pixel
+     */
+    public abstract int getAlpha(int pixel);
+
+    /**
+     * Gets the array of sizes of the different components.
+     * 
+     * @return the array of sizes of the different components
+     */
+    public int[] getComponentSize() {
+        if (bits != null) {
+            return bits.clone();
+        }
+        return null;
+    }
+
+    /**
+     * Checks if the alpha component is premultiplied.
+     * 
+     * @return true, if the alpha component is premultiplied
+     */
+    public final boolean isAlphaPremultiplied() {
+        return isAlphaPremultiplied;
+    }
+
+    /**
+     * Checks whether this color model supports alpha.
+     * 
+     * @return true, if this color model has alpha
+     */
+    public final boolean hasAlpha() {
+        return hasAlpha;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp;
+
+        if (hasAlpha) {
+            hash ^= 1;
+            hash <<= 8;
+        }
+        if (isAlphaPremultiplied) {
+            hash ^= 1;
+            hash <<= 8;
+        }
+
+        tmp = hash >>> 24;
+        hash ^= numColorComponents;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= transparency;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= cs.getType();
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= pixel_bits;
+        hash <<= 8;
+        hash |= tmp;
+
+        tmp = hash >>> 24;
+        hash ^= transferType;
+        hash <<= 8;
+        hash |= tmp;
+
+        if (bits != null) {
+
+            for (int element : bits) {
+                tmp = hash >>> 24;
+                hash ^= element;
+                hash <<= 8;
+                hash |= tmp;
+            }
+
+        }
+
+        return hash;
+    }
+
+    public int getTransparency() {
+        return transparency;
+    }
+
+    /**
+     * Gets the transfer type, which is the type of Java primitive
+     * value that corresponds to the bit length per pixel: either 
+     * {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT}, 
+     * {@link DataBuffer#TYPE_INT}, or {@link DataBuffer#TYPE_UNDEFINED}.
+     * 
+     * @return the transfer type
+     */
+    public final int getTransferType() {
+        return transferType;
+    }
+
+    /**
+     * Gets the pixel size in bits.
+     * 
+     * @return the pixel size
+     */
+    public int getPixelSize() {
+        return pixel_bits;
+    }
+
+    /**
+     * Gets the number of components of this color model.
+     * 
+     * @return the number of components
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+    /**
+     * Gets the number of color components of this color model.
+     * 
+     * @return the number color components
+     */
+    public int getNumColorComponents() {
+        return numColorComponents;
+    }
+
+    /**
+     * Gets the default RGB color model.
+     * 
+     * @return the default RGB color model
+     */
+    public static ColorModel getRGBdefault() {
+        if (RGBdefault == null) {
+            RGBdefault = new DirectColorModel(32, 0x00ff0000, 0x0000ff00,
+                    0x000000ff, 0xff000000);
+        }
+        return RGBdefault;
+    }
+
+    /*
+     * Construct INT pixel representation from Object
+     * @param obj
+     *
+     * @return
+     */
+    /**
+     * Construct pixel.
+     * 
+     * @param obj the obj
+     * 
+     * @return the int
+     */
+    private int constructPixel(Object obj) {
+        int pixel = 0;
+
+        switch (getTransferType()) {
+
+        case DataBuffer.TYPE_BYTE:
+            byte[] bPixel = (byte[]) obj;
+            if(bPixel.length > 1) {
+                // awt.275=This pixel representation is not suuported by tis Color Model
+                throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+            }
+            pixel = bPixel[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short[] sPixel = (short[]) obj;
+            if(sPixel.length > 1) {
+                // awt.275=This pixel representation is not suuported by tis Color Model
+                throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+            }
+            pixel = sPixel[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int[] iPixel = (int[]) obj;
+            if(iPixel.length > 1) {
+                // awt.275=This pixel representation is not suuported by tis Color Model
+                throw new UnsupportedOperationException(Messages.getString("awt.275")); //$NON-NLS-1$
+            }
+            pixel = iPixel[0];
+            break;
+
+        default:
+            // awt.22D=This transferType ( {0} ) is not supported by this color model
+            throw new UnsupportedOperationException(Messages.getString("awt.22D", //$NON-NLS-1$
+                   transferType));
+
+        }
+        return pixel;
+    }
+
+    /**
+     * Gets the transfer type, which is the type of Java primitive
+     * value that corresponds to the bit length per pixel: either 
+     * {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT}, 
+     * {@link DataBuffer#TYPE_INT}, or {@link DataBuffer#TYPE_UNDEFINED}.
+     * 
+     * @param bits the array of component masks
+     * 
+     * @return the transfer type
+     */
+    static int getTransferType(int bits) {
+        if (bits <= 8) {
+            return DataBuffer.TYPE_BYTE;
+        } else if (bits <= 16) {
+            return DataBuffer.TYPE_USHORT;
+        } else if (bits <= 32) {
+            return DataBuffer.TYPE_INT;
+        } else {
+            return DataBuffer.TYPE_UNDEFINED;
+        }
+    }
+
+    @Override
+    public void finalize() {
+        // This method is added for the API compatibility
+        // Don't need to call super since Object's finalize is always empty
+    }
+}
diff --git a/awt/java/awt/image/ComponentColorModel.java b/awt/java/awt/image/ComponentColorModel.java
new file mode 100644
index 0000000..a152f55
--- /dev/null
+++ b/awt/java/awt/image/ComponentColorModel.java
@@ -0,0 +1,1471 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.color.ColorSpace;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class ComponentColorModel represents a color model that is defined 
+ * in terms of its components.
+ */
+public class ComponentColorModel extends ColorModel {
+
+    /** The signed. */
+    private boolean signed;   // Pixel samples are signed.
+                              // Samples with TransferType DataBuffer.TYPE_BYTE,
+                              // DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT - 
+                              // unsigned. Samples with others TransferType - 
+                              // signed.
+
+    /** The integral. */
+    private boolean integral; // Pixel samples are integral.
+                              // Samples with TransferType DataBuffer.TYPE_BYTE,
+                              // DataBuffer.TYPE_USHORT, DataBuffer.Short and 
+                              // DataBuffer.TYPE_INT - integral.
+
+    /** The scale factors. */
+    private float scaleFactors[]; // Array of factors for reduction components 
+                                  // values into the form scaled from 0 to 255
+
+    /** The donot support unnormalized. */
+    private boolean donotSupportUnnormalized; // This Color Model don't support
+                                              // unnormolized form 
+
+    /** The need alpha divide. */
+    private boolean needAlphaDivide; // hasAlpha && isAlphaPremultiplied
+
+    /** The calc value. */
+    private boolean calcValue;       // Value was culculated
+
+    /** The need scale. */
+    private boolean needScale;       // Normalized value need to scale
+
+    /** The min vals. */
+    private float minVals[];         // Array of Min normalized values
+
+    /** The ranges. */
+    private float ranges[];          // Array of range normalized values  
+
+    /** The alpha lut. */
+    private byte alphaLUT[];         // Lookup table for scale alpha value
+
+    /** The color lu ts. */
+    private byte colorLUTs[][];      // Lookup tables for scale color values
+
+    /** The from_ linea r_ rg b_ lut. */
+    private byte from_LINEAR_RGB_LUT[];  // Lookup table for conversion from
+                                         // Linear RGB Color Space into sRGB
+
+    /** The to_ linea r_8 rg b_ lut. */
+    private byte to_LINEAR_8RGB_LUT[];   // Lookup table for conversion from
+                                         // sRGB Color Space into Linear RGB 
+                                         // 8 bit 
+
+    /** The to_ linea r_16 rg b_ lut. */
+    private short to_LINEAR_16RGB_LUT[]; // Lookup table for conversion from
+                                         // sRGB Color Space into Linear RGB 
+                                         // 16 bit 
+
+    /** The LINEA r_ rg b_ length. */
+    private int LINEAR_RGB_Length;       // Linear RGB bit length
+
+    /** The factor. */
+    private float fFactor;               // Scale factor
+
+    /** The is_s rgb. */
+    private boolean is_sRGB;             // ColorModel has sRGB ColorSpace  
+
+    /** The is_ linea r_ rgb. */
+    private boolean is_LINEAR_RGB;       // Color Model has Linear RGB Color 
+                                         // Space 
+
+    /**
+     * Instantiates a new component color model.
+     * 
+     * @param colorSpace the color space
+     * @param bits the array of component masks
+     * @param hasAlpha whether the color model has alpha
+     * @param isAlphaPremultiplied whether the alpha is premultiplied
+     * @param transparency the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     */
+     public ComponentColorModel(ColorSpace colorSpace, int bits[],
+            boolean hasAlpha, boolean isAlphaPremultiplied, int transparency,
+            int transferType) {
+        super(createPixelBits(colorSpace, hasAlpha, transferType),
+                validateBits(bits, colorSpace, hasAlpha, transferType),
+                colorSpace, hasAlpha, isAlphaPremultiplied, transparency,
+                transferType);
+
+        needScale = false;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_INT:
+            signed = false;
+            integral = true;
+            donotSupportUnnormalized = false;
+            scaleFactors = new float[numComponents];
+            for (int i = 0; i < numColorComponents; i++) {
+                scaleFactors[i] = 1.0f / maxValues[i];
+                if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                    donotSupportUnnormalized = true;
+                }
+            }
+            if (hasAlpha) {
+                maxValues[numColorComponents] =
+                    (1 << bits[numColorComponents]) - 1;
+                scaleFactors[numColorComponents] =
+                    1.0f / maxValues[numColorComponents];
+            }
+            break;
+        case DataBuffer.TYPE_SHORT:
+            signed = true;
+            integral = true;
+            donotSupportUnnormalized = true;
+            scaleFactors = new float[numComponents];
+            for (int i = 0; i < numComponents; i++) {
+                maxValues[i] = Short.MAX_VALUE;
+                scaleFactors[i] = 1.0f / maxValues[i];
+                if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                    needScale = true;
+                }
+            }
+            if (needScale) {
+                minVals = new float[numColorComponents];
+                ranges = new float[numColorComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    minVals[i] = cs.getMinValue(i);
+                    ranges[i] = cs.getMaxValue(i) - minVals[i];
+                }
+            }
+            break;
+        case DataBuffer.TYPE_FLOAT:
+        case DataBuffer.TYPE_DOUBLE:
+            signed = true;
+            integral = false;
+            donotSupportUnnormalized = true;
+            break;
+        default:
+            // awt.215=transferType is not one of DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT,
+            //          DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or
+            //          DataBuffer.TYPE_DOUBLE
+            throw new IllegalArgumentException(Messages.getString("awt.215")); //$NON-NLS-1$
+        }
+
+        needAlphaDivide = hasAlpha && isAlphaPremultiplied;
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new component color model.
+     * 
+     * @param colorSpace the color space
+     * @param hasAlpha whether the color model has alpha
+     * @param isAlphaPremultiplied whether the alpha is premultiplied
+     * @param transparency the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     */
+    public ComponentColorModel(ColorSpace colorSpace, boolean hasAlpha,
+            boolean isAlphaPremultiplied, int transparency, int transferType) {
+        
+        this(colorSpace, 
+                createPixelBitsArray(colorSpace, hasAlpha, transferType), 
+                hasAlpha, 
+                isAlphaPremultiplied, 
+                transparency,
+                transferType);
+    }
+
+    /**
+     * Validate bits.
+     * 
+     * @param bits the bits
+     * @param colorSpace the color space
+     * @param hasAlpha the has alpha
+     * @param transferType the transfer type
+     * 
+     * @return the int[]
+     */
+    private static int[] validateBits(int bits[], ColorSpace colorSpace,
+            boolean hasAlpha, int transferType) {
+        if (bits != null) {
+            return bits;
+        }
+
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+        bits = new int[numComponents];
+
+        int componentLength = DataBuffer.getDataTypeSize(transferType);
+
+        for (int i = 0; i < numComponents; i++) {
+            bits[i] = componentLength;
+        }
+
+        return bits;
+    }
+
+    /**
+     * Creates the pixel bits.
+     * 
+     * @param colorSpace the color space
+     * @param hasAlpha the has alpha
+     * @param transferType the transfer type
+     * 
+     * @return the int
+     */
+    private static int createPixelBits(ColorSpace colorSpace, boolean hasAlpha,
+            int transferType) {
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+        int componentLength = DataBuffer.getDataTypeSize(transferType);
+        return numComponents * componentLength;
+    }
+
+    /**
+     * Creates the pixel bits array.
+     * 
+     * @param colorSpace the color space
+     * @param hasAlpha the has alpha
+     * @param transferType the transfer type
+     * 
+     * @return the int[]
+     */
+    private static int[] createPixelBitsArray(ColorSpace colorSpace, 
+            boolean hasAlpha, int transferType) {
+        
+        int numComponents = colorSpace.getNumComponents();
+        if (hasAlpha) {
+            numComponents++;
+        }
+
+        int bits[] = new int[numComponents];
+        for(int i = 0; i < numComponents; i++){
+            bits[i] = DataBuffer.getDataTypeSize(transferType);
+        }
+        return bits;
+    }
+
+    @Override
+    public Object getDataElements(int components[], int offset, Object obj) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (offset + numComponents > components.length) {
+            // awt.216=The components array is not large enough to hold all the color and alpha components
+            throw new IllegalArgumentException(Messages.getString("awt.216")); //$NON-NLS-1$
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (obj == null) {
+                ba = new byte[numComponents];
+            } else {
+                ba = (byte[]) obj;
+            }
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                ba[i] = (byte) components[idx];
+            }
+            return ba;
+        case DataBuffer.TYPE_USHORT:
+            short sa[];
+            if (obj == null) {
+                sa = new short[numComponents];
+            } else {
+                sa = (short[]) obj;
+            }
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                sa[i] = (short) components[idx];
+            }
+            return sa;
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (obj == null) {
+                ia = new int[numComponents];
+            } else {
+                ia = (int[]) obj;
+            }
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                ia[i] = components[idx];
+            }
+            return ia;
+        default:
+            // awt.217=The transfer type of this ComponentColorModel is not one
+            //          of the following transfer types: DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+            throw new UnsupportedOperationException(Messages
+                    .getString("awt.217")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public Object getDataElements(float normComponents[], int normOffset,
+            Object obj) {
+        if (needScale) {
+            for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                normComponents[idx] =
+                    (normComponents[idx] - minVals[i]) / ranges[i];
+            }
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (obj == null) {
+                ba = new byte[numComponents];
+            } else {
+                ba = (byte[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = normOffset; i < numColorComponents;
+                    i++, idx++) {
+                    ba[i] = (byte) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                ba[numColorComponents] =
+                    (byte) (normComponents[normOffset + numColorComponents] *
+                            maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    ba[idx] =
+                        (byte) (normComponents[idx] * maxValues[i] + 0.5f);
+                }
+            }
+            return ba;
+
+        case DataBuffer.TYPE_USHORT:
+            short usa[];
+            if (obj == null) {
+                usa = new short[numComponents];
+            } else {
+                usa = (short[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    usa[i] = (short) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                usa[numColorComponents] = (short) (alpha *
+                        maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    usa[i] = (short) (normComponents[idx] *
+                            maxValues[i] + 0.5f);
+                }
+            }
+            return usa;
+
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (obj == null) {
+                ia = new int[numComponents];
+            } else {
+                ia = (int[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    ia[i] = (int) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                ia[numColorComponents] = (int) (alpha *
+                        maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    ia[i] = (int) (normComponents[idx] * maxValues[i] + 0.5f);
+                }
+            }
+            return ia;
+
+        case DataBuffer.TYPE_SHORT:
+            short sa[];
+            if (obj == null) {
+                sa = new short[numComponents];
+            } else {
+                sa = (short[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    sa[i] = (short) (normComponents[idx] * alpha *
+                            maxValues[i] + 0.5f);
+                }
+                sa[numColorComponents] = (short) (alpha *
+                        maxValues[numColorComponents] + 0.5f);
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    sa[i] = (short) (normComponents[idx] *
+                            maxValues[i] + 0.5f);
+                }
+            }
+            return sa;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fa[];
+            if (obj == null) {
+                fa = new float[numComponents];
+            } else {
+                fa = (float[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                float alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    fa[i] = normComponents[idx] * alpha;
+                }
+                fa[numColorComponents] = alpha;
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    fa[i] = normComponents[idx];
+                }
+            }
+            return fa;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double da[];
+            if (obj == null) {
+                da = new double[numComponents];
+            } else {
+                da = (double[]) obj;
+            }
+
+            if (needAlphaDivide) {
+                double alpha = normComponents[normOffset + numColorComponents];
+                for (int i = 0, idx = 0; i < numColorComponents; i++, idx++) {
+                    da[i] = normComponents[idx] * alpha;
+                }
+                da[numColorComponents] = alpha;
+            } else {
+                for (int i = 0, idx = normOffset; i < numComponents;
+                    i++, idx++) {
+                    da[i] = normComponents[idx];
+                }
+            }
+            return da;
+
+        default:
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public Object getDataElements(int rgb, Object pixel) {
+        float normComp[];
+        float comp[];
+
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+        int alpha = (rgb >> 24) & 0xff;
+
+        comp = new float[3];
+        if (is_sRGB || is_LINEAR_RGB) {
+            if (is_LINEAR_RGB) {
+                if (LINEAR_RGB_Length == 8) {
+                    red = to_LINEAR_8RGB_LUT[red] & 0xff;
+                    green = to_LINEAR_8RGB_LUT[green] & 0xff;
+                    blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
+                } else {
+                    red = to_LINEAR_16RGB_LUT[red] & 0xffff;
+                    green = to_LINEAR_16RGB_LUT[green] & 0xffff;
+                    blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
+                }
+            }
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            if (!hasAlpha) {
+                normComp = comp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = comp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        } else {
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            float[] defComp = cs.fromRGB(comp);
+            if (!hasAlpha) {
+                normComp = defComp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = defComp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        }
+        if(hasAlpha && isAlphaPremultiplied){
+            normComp[0] *= normComp[numColorComponents];
+            normComp[1] *= normComp[numColorComponents];
+            normComp[2] *= normComp[numColorComponents];
+        }
+
+        return getDataElements(normComp, 0, pixel);
+    }
+
+    @Override
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        if(!hasAlpha) {
+            return null;
+        }
+
+        int x = raster.getMinX();
+        int y = raster.getMinY();
+        int bandList[] = new int[1];
+        bandList[0] = raster.getNumBands() - 1;
+
+        return raster.createWritableChild(x, y, raster.getWidth(),
+                raster.getHeight(), x, y, bandList);
+    }
+
+    @Override
+    public ColorModel coerceData(WritableRaster raster,
+            boolean isAlphaPremultiplied) {
+        if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
+            return this;
+        }
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        if (isAlphaPremultiplied) {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                float alphaFactor = maxValues[numColorComponents];
+                int iComponents[] = null;
+                int iTransparentComponents[] = new int[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        iComponents = raster.getPixel(x, minY,
+                                iComponents);
+                        if (iComponents[numColorComponents] == 0) {
+                            raster.setPixel(x, minY, iTransparentComponents);
+                        } else {
+                            float alpha =
+                                iComponents[numColorComponents] /
+                                    alphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                iComponents[n] =
+                                    (int) (alpha * iComponents[n] + 0.5f);
+                            }
+                            raster.setPixel(x, minY, iComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+                float sAlphaFactor = maxValues[numColorComponents];
+                short sComponents[] = null;
+                short sTransparentComponents[] = new short[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        sComponents = (short[]) raster.getDataElements(x, minY,
+                                sComponents);
+                        if (sComponents[numColorComponents] == 0) {
+                            raster.setDataElements(x, minY,
+                                    sTransparentComponents);
+                        } else {
+                            float alpha =
+                                sComponents[numColorComponents] /
+                                sAlphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                sComponents[n] =
+                                    (byte) (alpha * sComponents[n] + 0.5f);
+                            }
+                            raster.setDataElements(x, minY, sComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fComponents[] = null;
+                float fTransparentComponents[] = new float[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        fComponents = raster.getPixel(x, minY, fComponents);
+                        if (fComponents[numColorComponents] == 0.0f) {
+                            raster.setDataElements(x, minY,
+                                    fTransparentComponents);
+                        } else {
+                            float alpha = fComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                fComponents[n] = fComponents[n] * alpha;
+                            }
+                            raster.setPixel(x, minY, fComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double dComponents[] = null;
+                double dTransparentComponents[] = new double[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        dComponents = raster.getPixel(x, minY, dComponents);
+                        if (dComponents[numColorComponents] == 0.0) {
+                            raster.setPixel(x, minY, dTransparentComponents);
+                        } else {
+                            double alpha = dComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                dComponents[n] = dComponents[n] * alpha;
+                            }
+                            raster.setPixel(x, minY, dComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            default:
+                // awt.219=This transferType is not supported by this color model
+                throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+            }
+        } else {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                float alphaFactor = maxValues[numColorComponents];
+                int iComponents[] = null;
+                int iTransparentComponents[] = new int[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        iComponents = raster.getPixel(x, minY,
+                                iComponents);
+                        if (iComponents[numColorComponents] == 0) {
+                            raster.setPixel(x, minY, iTransparentComponents);
+                        } else {
+                            float alpha =
+                                iComponents[numColorComponents] /
+                                    alphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                iComponents[n] =
+                                    (int) (iComponents[n] /
+                                            alpha + 0.5f);
+                            }
+                            raster.setPixel(x, minY, iComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_SHORT:
+                float sAlphaFactor = maxValues[numColorComponents];
+                short sComponents[] = null;
+                short sTransparentComponents[] = new short[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        sComponents = (short[]) raster.getDataElements(x, minY,
+                                sComponents);
+                        if (sComponents[numColorComponents] == 0) {
+                            raster.setDataElements(x, minY,
+                                    sTransparentComponents);
+                        } else {
+                            float alpha =
+                                sComponents[numColorComponents] /
+                                    sAlphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                sComponents[n] =
+                                    (byte) (sComponents[n] /
+                                            alpha + 0.5f);
+                            }
+                            raster.setDataElements(x, minY, sComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_FLOAT:
+                float fComponents[] = null;
+                float fTransparentComponents[] = new float[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        fComponents = raster.getPixel(x, minY, fComponents);
+                        if (fComponents[numColorComponents] == 0.0f) {
+                            raster.setDataElements(x, minY,
+                                    fTransparentComponents);
+                        } else {
+                            float alpha = fComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                fComponents[n] = fComponents[n] / alpha;
+                            }
+                            raster.setPixel(x, minY, fComponents);
+                        }
+                    }
+
+                }
+                break;
+
+            case DataBuffer.TYPE_DOUBLE:
+                double dComponents[] = null;
+                double dTransparentComponents[] = new double[numComponents];
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        dComponents = raster.getPixel(x, minY, dComponents);
+                        if (dComponents[numColorComponents] == 0.0) {
+                            raster.setPixel(x, minY, dTransparentComponents);
+                        } else {
+                            double alpha = dComponents[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                dComponents[n] = dComponents[n] / alpha;
+                            }
+                            raster.setPixel(x, minY, dComponents);
+                        }
+                    }
+
+                }
+                break;
+            default:
+                // awt.219=This transferType is not supported by this color model
+                throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+            }
+        }
+
+        if (!signed) {
+            return new ComponentColorModel(cs, bits, hasAlpha,
+                    isAlphaPremultiplied, transparency, transferType);
+        }
+
+        return new ComponentColorModel(cs, null, hasAlpha,
+                isAlphaPremultiplied, transparency, transferType);
+    }
+
+    @Override
+    public int[] getComponents(Object pixel, int[] components, int offset) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[offset + numComponents];
+        } else if (offset + numComponents > components.length) {
+            // awt.218=The components array is not large enough to hold all the color and alpha components
+            throw new IllegalArgumentException(Messages.getString("awt.218")); //$NON-NLS-1$
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                components[idx] = ba[i] & 0xff;
+            }
+            return components;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) pixel;
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                components[idx] = sa[i] & 0xffff;
+            }
+            return components;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            for (int i = 0, idx = offset; i < numComponents; i++, idx++) {
+                components[idx] = ia[i];
+            }
+            return components;
+
+        default:
+            // awt.217=The transfer type of this ComponentColorModel is not one
+            //          of the following transfer types: DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+            throw new UnsupportedOperationException(Messages
+                    .getString("awt.217")); //$NON-NLS-1$
+        }
+
+    }
+
+    @Override
+    public float[] getNormalizedComponents(Object pixel,
+            float normComponents[], int normOffset) {
+
+        if (normComponents == null) {
+            normComponents = new float[numComponents + normOffset];
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = (ba[i] & 0xff) * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short usa[] = (short[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = (usa[i] & 0xffff)
+                        * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = ia[i] * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+            short sa[] = (short[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = sa[i] * scaleFactors[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fa[] = (float[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = fa[i];
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double da[] = (double[]) pixel;
+            for (int i = 0, idx = normOffset; i < numComponents; i++, idx++) {
+                normComponents[idx] = (float) da[i];
+            }
+            break;
+
+        default:
+            // awt.21A=This ComponentColorModel does not support this transferType
+            throw new IllegalArgumentException(Messages.getString("awt.21A")); //$NON-NLS-1$
+        }
+
+        if (needAlphaDivide) {
+            float alpha = normComponents[normOffset + numColorComponents];
+            for (int i = 0, idx = normOffset; i < numColorComponents;
+                i++, idx++) {
+                normComponents[idx] /= alpha;
+            }
+        }
+
+        if (needScale) {
+            for (int i = 0, idx = normOffset; i < numColorComponents;
+                i++, idx++) {
+                normComponents[idx] = minVals[i] +
+                    ranges[i] * normComponents[idx];
+            }
+        }
+        return normComponents;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ComponentColorModel)) {
+            return false;
+        }
+        return super.equals(obj);
+    }
+
+    @Override
+    public int getRed(Object inData) {
+        return getRGBComponent(inData, 0);
+    }
+
+    @Override
+    public int getRGB(Object inData) {
+        int alpha = getAlpha(inData);
+        if (cs.getType() == ColorSpace.TYPE_GRAY) {
+            int gray = getRed(inData);
+            return (alpha << 24 | gray << 16 | gray << 8 | gray);
+        }
+        return (alpha << 24 | getRed(inData) << 16 | getGreen(inData) << 8 |
+                getBlue(inData));
+    }
+
+    @Override
+    public int getGreen(Object inData) {
+        return getRGBComponent(inData, 1);
+    }
+
+    @Override
+    public int getBlue(Object inData) {
+        return getRGBComponent(inData, 2);
+    }
+
+    @Override
+    public int getAlpha(Object inData) {
+        if (!hasAlpha) {
+            return 255;
+        }
+        int alpha = 0;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE: {
+            byte ba[] = (byte[]) inData;
+            alpha = ba[numColorComponents] & 0xff;
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_USHORT: {
+            short usa[] = (short[]) inData;
+            alpha = usa[numColorComponents] & 0xffff;
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_INT: {
+            int ia[] = (int[]) inData;
+            alpha = ia[numColorComponents];
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_SHORT: {
+            short sa[] = (short[]) inData;
+            alpha = sa[numColorComponents];
+            if (bits[numColorComponents] != 8) {
+                return alphaLUT[alpha] & 0xff;
+            }
+            return alpha;
+        }
+        case DataBuffer.TYPE_FLOAT: {
+            float fa[] = (float[]) inData;
+            return (int) (fa[numColorComponents] * 255.0f + 0.5f);
+        }
+        case DataBuffer.TYPE_DOUBLE: {
+            double da[] = (double[]) inData;
+            return (int) (da[numColorComponents] * 255.0 + 0.5);
+        }
+        default: {
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        }
+    }
+
+    @Override
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        SampleModel sm = createCompatibleSampleModel(w, h);
+        DataBuffer db = sm.createDataBuffer();
+        return Raster.createWritableRaster(sm, db, null);
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (!(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+        if (numComponents != sm.getNumBands()) {
+            return false;
+        }
+        if (transferType != sm.getTransferType()) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        int bandOffsets[] = new int[numComponents];
+        for (int i = 0; i < numComponents; i++) {
+            bandOffsets[i] = i;
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+        case DataBuffer.TYPE_USHORT:
+            return new PixelInterleavedSampleModel(transferType, w, h,
+                    numComponents, w * numComponents, bandOffsets);
+
+        default:
+            return new ComponentSampleModel(transferType, w, h, numComponents,
+                    w * numComponents, bandOffsets);
+        }
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        SampleModel sm = raster.getSampleModel();
+        if (!(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+
+        if (sm.getNumBands() != numComponents) {
+            return false;
+        }
+        if (raster.getTransferType() != transferType) {
+            return false;
+        }
+
+        int sampleSizes[] = sm.getSampleSize();
+        for (int i = 0; i < numComponents; i++) {
+            if (bits[i] != sampleSizes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public float[] getNormalizedComponents(int components[], int offset,
+            float normComponents[], int normOffset) {
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        return super.getNormalizedComponents(components, offset,
+                normComponents, normOffset);
+    }
+
+    @Override
+    public int getDataElement(int[] components, int offset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+        return components[offset];
+    }
+
+    @Override
+    public int[] getUnnormalizedComponents(float[] normComponents,
+            int normOffset, int[] components, int offset) {
+
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (normComponents.length - normOffset < numComponents) {
+            // awt.21B=The length of normComponents minus normOffset is less than numComponents
+            throw new IllegalArgumentException(Messages.getString("awt.21B")); //$NON-NLS-1$
+        }
+
+        return super.getUnnormalizedComponents(normComponents, normOffset,
+                components, offset);
+    }
+
+    @Override
+    public int getDataElement(float normComponents[], int normOffset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        Object pixel = getDataElements(normComponents, normOffset, null);
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            return ba[0] & 0xff;
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) pixel;
+            return sa[0] & 0xffff;
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            return ia[0];
+        default:
+            // awt.211=Pixel values for this ColorModel are not conveniently
+            //          representable as a single int
+            throw new IllegalArgumentException(Messages.getString("awt.211")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public int[] getComponents(int pixel, int components[], int offset) {
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+        if (donotSupportUnnormalized) {
+            // awt.213=This ComponentColorModel does not support the unnormalized form
+            throw new IllegalArgumentException(Messages.getString("awt.213")); //$NON-NLS-1$
+        }
+
+        if (components == null) {
+            components = new int[offset + 1];
+        }
+
+        components[offset] = pixel & maxValues[0];
+        return components;
+    }
+
+    @Override
+    public int getRed(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int) (rgb[0] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) |
+               (getGreen(pixel) << 8) | getBlue(pixel);
+    }
+
+    @Override
+    public int getGreen(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int) (rgb[1] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getBlue(int pixel) {
+        float rgb[] = toRGB(pixel);
+        return (int) (rgb[2] * 255.0f + 0.5f);
+    }
+
+    @Override
+    public int getAlpha(int pixel) {
+
+        // This method throw IllegalArgumentException according to 
+        // Java API Spacification
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+
+        return 255;
+    }
+
+    /**
+     * Initialization of Lookup tables.
+     */
+    private void initLUTs() {
+        is_sRGB = cs.isCS_sRGB();
+        is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
+
+        if (hasAlpha && bits[numColorComponents] != 8 && integral) {
+            alphaLUT = new byte[maxValues[numColorComponents] + 1];
+            for (int i = 0; i <= maxValues[numColorComponents]; i++) {
+                alphaLUT[i] = (byte) (scaleFactors[numColorComponents] * i + 
+                        0.5f);
+            }
+        }
+
+        if (is_LINEAR_RGB) {
+            if (maxBitLength > 8) {
+                LINEAR_RGB_Length = 16;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom16lRGBtosRGB_LUT();
+                to_LINEAR_16RGB_LUT =
+                    LUTColorConverter.getFromsRGBto16lRGB_LUT();
+            } else {
+                LINEAR_RGB_Length = 8;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom8lRGBtosRGB_LUT();
+                to_LINEAR_8RGB_LUT =
+                    LUTColorConverter.getFromsRGBto8lRGB_LUT();
+            }
+            fFactor = ((1 << LINEAR_RGB_Length) - 1);
+        } else {
+            fFactor = 255.0f;
+        }
+
+        if (!isAlphaPremultiplied && integral) {
+            colorLUTs = new byte[3][];
+
+            if (is_sRGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != 8) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            colorLUTs[i][j] =
+                                (byte) (scaleFactors[i] * j + 0.5f);
+                        }
+                    }
+                }
+            }
+
+            if (is_LINEAR_RGB) {
+
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != LINEAR_RGB_Length) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            int idx;
+                            if (LINEAR_RGB_Length == 8) {
+                                idx = (int) (scaleFactors[i] * j + 0.5f);
+                            } else {
+                                idx = (int) (scaleFactors[i] * j * 257.0f +
+                                        0.5f);
+                            }
+                            colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+    /**
+     * To rgb.
+     * 
+     * @param pixel - int representation of pixel
+     * 
+     * @return - array of normalized sRGB components
+     */
+    private float[] toRGB(int pixel) {
+        
+        // This method throw IllegalArgumentException according to 
+        // Java API Spacification
+        if (signed) {
+            // awt.210=The component value for this ColorModel is signed
+            throw new IllegalArgumentException(Messages.getString("awt.210")); //$NON-NLS-1$
+        }
+
+        if (numComponents > 1) {
+            // awt.212=There is more than one component in this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.212")); //$NON-NLS-1$
+        }
+
+        Object obj = null;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = new byte[1];
+            ba[0] = (byte) pixel;
+            obj = ba;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = new short[1];
+            sa[0] = (short) pixel;
+            obj = sa;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = new int[1];
+            ia[0] = pixel;
+            obj = ia;
+            break;
+
+        }
+
+        return cs.toRGB(getNormalizedComponents(obj, null, 0));
+    }
+
+    /**
+     * Gets the rgb component.
+     * 
+     * @param pixel - pixel
+     * @param idx - index of component
+     * 
+     * @return - RGB value from 0 to 255 pixel's component
+     */
+    private int getRGBComponent(Object pixel, int idx) {
+        if (is_sRGB) {
+            int comp = getDefComponent(pixel, idx);
+            if (calcValue || bits[idx] == 8) {
+                return comp;
+            }
+            return colorLUTs[idx][comp] & 0xff;
+        } else if (is_LINEAR_RGB) {
+            int comp = getDefComponent(pixel, idx);
+            if (calcValue || bits[idx] == LINEAR_RGB_Length) {
+                return from_LINEAR_RGB_LUT[comp] & 0xff;
+            }
+            return colorLUTs[idx][comp] & 0xff;
+        }
+
+        float normComp[] = getNormalizedComponents(pixel, null, 0);
+        float rgbComp[] = cs.toRGB(normComp);
+        return (int) (rgbComp[idx] * 255.0f + 0.5f);
+    }
+
+    /**
+     * Gets the def component.
+     * 
+     * @param pixel - pixel
+     * @param idx - index of component
+     * 
+     * @return - tentative value of the pixel component
+     */
+    private int getDefComponent(Object pixel, int idx) {
+        int comp = 0;
+        calcValue = false;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            comp = ba[idx] & 0xff;
+            if (needAlphaDivide) {
+                int alpha = ba[numColorComponents] & 0xff;
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_USHORT:
+            short usa[] = (short[]) pixel;
+            comp = usa[idx] & 0xffff;
+            if (needAlphaDivide) {
+                int alpha = usa[numColorComponents] & 0xffff;
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            comp = ia[idx];
+            if (needAlphaDivide) {
+                int alpha = ia[numColorComponents];
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_SHORT:
+            short sa[] = (short[]) pixel;
+            comp = sa[idx];
+            if (needAlphaDivide) {
+                int alpha = sa[numColorComponents];
+                if (alpha == 0) {
+                    comp = 0;
+                } else {
+                    float normAlpha = scaleFactors[numColorComponents] * alpha;
+                    comp = (int) (comp * fFactor / normAlpha + 0.5f);
+                }
+                calcValue = true;
+            }
+            return comp;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fa[] = (float[]) pixel;
+            if (needAlphaDivide) {
+                float alpha = fa[numColorComponents];
+                if (fa[numColorComponents] == 0.0f) {
+                    comp = 0;
+                } else {
+                    comp = (int) (fa[idx] * fFactor / alpha + 0.5f);
+                }
+            } else {
+                comp = (int) (fa[idx] * fFactor + 0.5f);
+            }
+            calcValue = true;
+            return comp;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double da[] = (double[]) pixel;
+            if (needAlphaDivide) {
+                if (da[numColorComponents] == 0.0) {
+                    comp = 0;
+                } else {
+                    comp = (int) (da[idx] * fFactor / da[numColorComponents] + 
+                            0.5);
+                }
+            } else {
+                comp = (int) (da[idx] * fFactor + 0.5);
+            }
+            calcValue = true;
+            return comp;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/image/ComponentSampleModel.java b/awt/java/awt/image/ComponentSampleModel.java
new file mode 100644
index 0000000..2ff4f1a
--- /dev/null
+++ b/awt/java/awt/image/ComponentSampleModel.java
@@ -0,0 +1,690 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ComponentSampleModel class represents a set of image data whose 
+ * each element - the sample of a pixel - takes one data element of 
+ * the DataBuffer. 
+ * <p>
+ * The Bank indices denote the correspondence between the bank of data 
+ * buffers and a band of image data. The Pixel stride is the number of data 
+ * array elements between two samples for the same band on the same 
+ * scanline. The pixel stride for a BandedSampleModel is one. The Scanline 
+ * stride represents the number of data array elements between a  
+ * specified sample and the corresponding sample in the same column in 
+ * the next scanline. The array of band offsets gives the starting 
+ * offsets within each data banks of the in the DataBuffer. The bank 
+ * indices represents the indices within each bank of the DataBuffer 
+ * corresponding to a band of image data.
+ */
+public class ComponentSampleModel extends SampleModel {
+
+    /** The band offsets array of this ComponentSampleModel. */
+    protected int bandOffsets[];
+
+    /** The bank indices array of this ComponentSampleModel. */
+    protected int bankIndices[];
+
+    /** The number of bands in this ComponentSampleModel. */
+    protected int numBands;
+
+    /** The number banks of this ComponentSampleModel. */
+    protected int numBanks;
+
+    /** The scanline stride of this ComponentSampleModel. */
+    protected int scanlineStride;
+
+    /** The pixel stride of this ComponentSampleModel. */
+    protected int pixelStride;
+
+    /**
+     * Instantiates a new ComponentSampleModel with the specified
+     * properties.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param pixelStride the pixel stride of the image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bankIndices the array of the bank indices.
+     * @param bandOffsets the array of the band offsets.
+     */
+    public ComponentSampleModel(int dataType, int w, int h, int pixelStride,
+            int scanlineStride, int bankIndices[], int bandOffsets[]) {
+
+        super(dataType, w, h, bandOffsets.length);
+
+        if (pixelStride < 0) {
+            // awt.24B=Pixel stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24B")); //$NON-NLS-1$
+        }
+
+        if (scanlineStride < 0) {
+            // awt.24C=Scanline stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24C")); //$NON-NLS-1$
+        }
+
+        if (bankIndices.length != bandOffsets.length) {
+            // awt.24D=Bank Indices length must be equal Bank Offsets length
+            throw new IllegalArgumentException(Messages.getString("awt.24D")); //$NON-NLS-1$
+        }
+
+        this.pixelStride = pixelStride;
+        this.scanlineStride = scanlineStride;
+        this.bandOffsets = bandOffsets.clone();
+        this.bankIndices = bankIndices.clone();
+        this.numBands = bandOffsets.length;
+
+        int maxBank = 0;
+        for (int i = 0; i < bankIndices.length; i++) {
+            if (bankIndices[i] < 0) {
+                // awt.24E=Index of {0} bank must be >= 0
+                throw new IllegalArgumentException(Messages.getString("awt.24E", i)); //$NON-NLS-1$
+            }
+            if (bankIndices[i] > maxBank) {
+                maxBank = bankIndices[i];
+            }
+        }
+        this.numBanks = maxBank + 1;
+
+    }
+
+    /**
+     * Instantiates a new ComponentSampleModel with the specified
+     * properties.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param pixelStride the pixel stride of the image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bandOffsets the band offsets.
+     */
+    public ComponentSampleModel(int dataType, int w, int h, int pixelStride,
+            int scanlineStride, int bandOffsets[]) {
+
+        super(dataType, w, h, bandOffsets.length);
+        if (pixelStride < 0) {
+            // awt.24B=Pixel stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24B")); //$NON-NLS-1$
+        }
+
+        if (scanlineStride < 0) {
+            // awt.24C=Scanline stride must be >= 0
+            throw new IllegalArgumentException(Messages.getString("awt.24C")); //$NON-NLS-1$
+        }
+
+        this.pixelStride = pixelStride;
+        this.scanlineStride = scanlineStride;
+        this.bandOffsets = bandOffsets.clone();
+        this.numBands = bandOffsets.length;
+        this.numBanks = 1;
+
+        this.bankIndices = new int[numBands];
+        for (int i = 0; i < numBands; i++) {
+            bankIndices[i] = 0;
+        }
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            if (obj == null) {
+                bdata = new byte[numBands];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                bdata[i] = (byte) getSample(x, y, i, data);
+            }
+
+            obj = bdata;
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            if (obj == null) {
+                sdata = new short[numBands];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                sdata[i] = (short) getSample(x, y, i, data);
+            }
+
+            obj = sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            if (obj == null) {
+                idata = new int[numBands];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                idata[i] = getSample(x, y, i, data);
+            }
+
+            obj = idata;
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fdata[];
+            if (obj == null) {
+                fdata = new float[numBands];
+            } else {
+                fdata = (float[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                fdata[i] = getSampleFloat(x, y, i, data);
+            }
+
+            obj = fdata;
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double ddata[];
+            if (obj == null) {
+                ddata = new double[numBands];
+            } else {
+                ddata = (double[]) obj;
+            }
+
+            for (int i = 0; i < numBands; i++) {
+                ddata[i] = getSampleDouble(x, y, i, data);
+            }
+
+            obj = ddata;
+            break;
+        }
+
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            byte barr[] = (byte[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, barr[i] & 0xff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sarr[] = (short[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, sarr[i] & 0xffff, data);
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int iarr[] = (int[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, iarr[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float farr[] = (float[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, farr[i], data);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double darr[] = (double[]) obj;
+            for (int i = 0; i < numBands; i++) {
+                setSample(x, y, i, darr[i], data);
+            }
+            break;
+        }
+    }
+
+    /**
+     * Compares this ComponentSampleModel with the specified Object.
+     * 
+     * @param o the Object.
+     * 
+     * @return true, if the object is a ComponentSampleModel with 
+     * identical data values to this ComponentSampleModel, false otherwise. 
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof ComponentSampleModel)) {
+            return false;
+        }
+        ComponentSampleModel model = (ComponentSampleModel) o;
+        return this.width == model.width && this.height == model.height &&
+               this.numBands == model.numBands &&
+               this.dataType == model.dataType &&
+               Arrays.equals(this.bandOffsets, model.bandOffsets) &&
+               Arrays.equals(this.bankIndices, model.bankIndices) &&
+               this.numBands == model.numBands &&
+               this.numBanks == model.numBanks &&
+               this.scanlineStride == model.scanlineStride &&
+               this.pixelStride == model.pixelStride;
+    }
+
+    /** 
+     * @see java.awt.image.SampleModel#createSubsetSampleModel(int[])
+     */
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands.length > this.numBands) {
+            // awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int indices[] = new int[bands.length];
+        int offsets[] = new int[bands.length];
+
+        for (int i = 0; i < bands.length; i++) {
+            indices[i] = bankIndices[bands[i]];
+            offsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new ComponentSampleModel(dataType, width, height, pixelStride,
+                scanlineStride, indices, offsets);
+
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new ComponentSampleModel(dataType, w, h, pixelStride,
+                pixelStride * w, bankIndices, bandOffsets);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        int pixel[];
+
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElem(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b]);
+    }
+
+    @Override
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemFloat(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b]);
+    }
+
+    @Override
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        return data.getElemDouble(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b]);
+    }
+
+    @Override
+    public int[] getPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x > this.width || x + w > this.width
+                || y > this.height || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixels[] = null;
+        int idx = 0;
+
+        if (iArray == null) {
+            pixels = new int[w * h * numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+
+        return pixels;
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElem(bankIndices[b], y * scanlineStride + x * pixelStride
+                + bandOffsets[b], s);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+        
+        if (data == null) {
+            // awt.295=data is null
+            throw new NullPointerException(Messages.getString("awt.295")); //$NON-NLS-1$
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemFloat(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b], s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        data.setElemDouble(bankIndices[b], y * scanlineStride +
+                x * pixelStride + bandOffsets[b], s);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+
+        int maxOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+        }
+        int size = (height - 1) * scanlineStride +
+        (width - 1) * pixelStride + maxOffset + 1;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size, numBanks);
+            break;
+        case DataBuffer.TYPE_SHORT:
+            data = new DataBufferShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size, numBanks);
+            break;
+        case DataBuffer.TYPE_FLOAT:
+            data = new DataBufferFloat(size, numBanks);
+            break;
+        case DataBuffer.TYPE_DOUBLE:
+            data = new DataBufferDouble(size, numBanks);
+            break;
+        }
+
+        return data;
+
+    }
+
+    /**
+     * Gets the offset of the specified band of the specified pixel.
+     * 
+     * @param x the X coordinate of the pixel. 
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the offset of the specified band of the specified pixel.
+     */
+    public int getOffset(int x, int y, int b) {
+        return y * scanlineStride + x * pixelStride + bandOffsets[b];
+    }
+
+    /**
+     * Gets the offset of the first band of the specified pixel.
+     * 
+     * @param x the X coordinate of pixel. 
+     * @param y the Y coordinate of pixel.
+     * 
+     * @return the offset of the first band of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return y * scanlineStride + x * pixelStride + bandOffsets[0];
+    }
+
+    @Override
+    public final int getSampleSize(int band) {
+        return DataBuffer.getDataTypeSize(dataType);
+    }
+
+    @Override
+    public final int[] getSampleSize() {
+        int sampleSizes[] = new int[numBands];
+        int size = DataBuffer.getDataTypeSize(dataType);
+
+        for (int i = 0; i < numBands; i++) {
+            sampleSizes[i] = size;
+        }
+        return sampleSizes;
+    }
+
+    /**
+     * Gets an array of bank indices corresponding to this 
+     * ComponentSampleModel.
+     * 
+     * @return the array of bank indices.
+     */
+    public final int[] getBankIndices() {
+        return bankIndices.clone();
+    }
+
+    /**
+     * Gets an array of the band offsets corresponding to this 
+     * ComponentSampleModel.
+     * 
+     * @return the array of band offsets.
+     */
+    public final int[] getBandOffsets() {
+        return bandOffsets.clone();
+    }
+
+    /**
+     * Gets a hash code of this ComponentSampleModel object.
+     * 
+     * @return a hash code of this ComponentSampleModel object.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        for (int element : bandOffsets) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bankIndices) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        hash ^= pixelStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+
+        hash ^= scanlineStride;
+        return hash;
+    }
+
+    /**
+     * Gets the scanline stride of this ComponentSampleModel.
+     * 
+     * @return the scanline stride of this ComponentSampleModel.
+     */
+    public final int getScanlineStride() {
+        return scanlineStride;
+    }
+
+    /**
+     * Gets the pixel stride.
+     * 
+     * @return the pixel stride
+     */
+    public final int getPixelStride() {
+        return pixelStride;
+    }
+
+    @Override
+    public final int getNumDataElements() {
+        return numBands;
+    }
+
+}
+
+
+
diff --git a/awt/java/awt/image/ConvolveOp.java b/awt/java/awt/image/ConvolveOp.java
new file mode 100644
index 0000000..bb588bc
--- /dev/null
+++ b/awt/java/awt/image/ConvolveOp.java
@@ -0,0 +1,545 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 29, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The ConvolveOp class convolves from the source data
+ * to the destination using a convolution kernel. 
+ * Each output pixel is represented as the result of multiplying 
+ * the kernel and the surround of the input pixel.
+ */
+public class ConvolveOp implements BufferedImageOp, RasterOp {
+
+    /** 
+     * The Constant EDGE_ZERO_FILL indicates that pixels at the edge of 
+     * the destination image are set to zero. 
+     */
+    public static final int EDGE_ZERO_FILL = 0;
+
+    /** 
+     * The Constant EDGE_NO_OP indicates that pixels at the edge of 
+     * the source image are converted to the edge pixels in the 
+     * destination without modification.
+     */
+    public static final int EDGE_NO_OP = 1;
+
+    /** The kernel. */
+    private Kernel kernel;
+    
+    /** The edge cond. */
+    private int edgeCond;
+    
+    /** The rhs. */
+    private RenderingHints rhs = null;
+
+    static {
+        // TODO
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new ConvolveOp object with the specified Kernel
+     * and specified edges condition.
+     * 
+     * @param kernel the specified Kernel.
+     * @param edgeCondition the specified edge condition.
+     * @param hints the RenderingHints object, or null.
+     */
+    public ConvolveOp(Kernel kernel, int edgeCondition, RenderingHints hints) {
+        this.kernel = kernel;
+        this.edgeCond = edgeCondition;
+        this.rhs = hints;
+    }
+
+    /**
+     * Instantiates a new ConvolveOp object with the specified Kernel
+     * and EDGE_ZERO_FILL edge condition.
+     * 
+     * @param kernel the specified Kernel.
+     */
+    public ConvolveOp(Kernel kernel) {
+        this.kernel = kernel;
+        this.edgeCond = EDGE_ZERO_FILL;
+    }
+
+    /**
+     * Gets the Kernel object of this ConvolveOp.
+     * 
+     * @return the Kernel object of this ConvolveOp.
+     */
+    public final Kernel getKernel() {
+        return (Kernel) kernel.clone();
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return rhs;
+    }
+
+    /**
+     * Gets the edge condition of this ConvolveOp.
+     * 
+     * @return the edge condition: EDGE_NO_OP or EDGE_ZERO_FILL.
+     */
+    public int getEdgeCondition() {
+        return edgeCond;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+        }
+
+        if (dstCM instanceof IndexColorModel) {
+            dstCM = ColorModel.getRGBdefault();
+        }
+
+        WritableRaster r =
+                dstCM.isCompatibleSampleModel(src.getSampleModel()) ?
+                src.getRaster().createCompatibleWritableRaster(src.getWidth(), src.getHeight()) :
+                dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(
+                dstCM,
+                r,
+                dstCM.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (src == null) { // Should throw according to spec
+            // awt.256=Source raster is null
+            throw new NullPointerException(Messages.getString("awt.256")); //$NON-NLS-1$
+        }
+
+        if (src == dst){
+            // awt.257=Source raster is equal to destination
+            throw new IllegalArgumentException(Messages.getString("awt.257")); //$NON-NLS-1$
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else if (src.getNumBands() != dst.getNumBands()) {
+            // awt.258=Number of source bands ({0}) is not equal to number of destination bands ({1})
+            throw new IllegalArgumentException(
+                Messages.getString("awt.258", src.getNumBands(), dst.getNumBands())); //$NON-NLS-1$
+        }
+
+        // TODO
+        //if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM) != 0)
+            if (slowFilter(src, dst) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * 
+     * @return the int
+     */
+    private int slowFilter(Raster src, WritableRaster dst) {
+        try {
+            SampleModel sm = src.getSampleModel();
+
+            int numBands = src.getNumBands();
+            int srcHeight = src.getHeight();
+            int srcWidth = src.getWidth();
+
+            int xOrigin = kernel.getXOrigin();
+            int yOrigin = kernel.getYOrigin();
+            int kWidth = kernel.getWidth();
+            int kHeight = kernel.getHeight();
+            float[] data = kernel.getKernelData(null);
+
+            int srcMinX = src.getMinX();
+            int srcMinY = src.getMinY();
+            int dstMinX = dst.getMinX();
+            int dstMinY = dst.getMinY();
+
+            int srcConvMaxX = srcWidth - (kWidth - xOrigin - 1);
+            int srcConvMaxY = srcHeight - (kHeight - yOrigin - 1);
+
+            int[] maxValues = new int[numBands];
+            int[] masks = new int[numBands];
+            int[] sampleSizes = sm.getSampleSize();
+
+            for (int i=0; i < numBands; i++){
+                maxValues[i] = (1 << sampleSizes[i]) - 1;
+                masks[i] = ~(maxValues[i]);
+            }
+
+            // Processing bounds
+            float[] pixels = null;
+            pixels = src.getPixels(srcMinX, srcMinY, srcWidth, srcHeight, pixels);
+            float[] newPixels = new float[pixels.length];
+            int rowLength = srcWidth*numBands;
+            if (this.edgeCond == ConvolveOp.EDGE_NO_OP){
+                // top
+                int start = 0;
+                int length = yOrigin*rowLength;
+                System.arraycopy(pixels, start, newPixels, start, length);
+                // bottom
+                start = (srcHeight - (kHeight - yOrigin - 1))*rowLength;
+                length = (kHeight - yOrigin - 1)*rowLength;
+                System.arraycopy(pixels, start, newPixels, start, length);
+                // middle
+                length = xOrigin*numBands;
+                int length1 = (kWidth - xOrigin - 1)*numBands;
+                start = yOrigin*rowLength;
+                int start1 = (yOrigin+1)*rowLength - length1;
+                for (int i = yOrigin; i < (srcHeight - (kHeight - yOrigin - 1)); i ++) {
+                    System.arraycopy(pixels, start, newPixels, start, length);
+                    System.arraycopy(pixels, start1, newPixels, start1, length1);
+                    start +=rowLength;
+                    start1 +=rowLength;
+                }
+
+            }
+
+            // Cycle over pixels to be calculated
+            for (int i = yOrigin; i < srcConvMaxY; i++){
+                for (int j = xOrigin; j < srcConvMaxX; j++){
+
+                    // Take kernel data in backward direction, convolution
+                    int kernelIdx = data.length - 1;
+
+                    int pixelIndex = i * rowLength + j * numBands;
+                    for (int hIdx = 0, rasterHIdx = i - yOrigin;
+                         hIdx < kHeight;
+                         hIdx++, rasterHIdx++
+                            ){
+                        for (int wIdx = 0, rasterWIdx = j - xOrigin;
+                             wIdx < kWidth;
+                             wIdx++, rasterWIdx++
+                                ){
+                            int curIndex = rasterHIdx * rowLength + rasterWIdx * numBands;
+                            for (int idx=0; idx < numBands; idx++){
+                                newPixels[pixelIndex+idx] += data[kernelIdx] * pixels[curIndex+idx];
+                            }
+                            kernelIdx--;
+                        }
+                    }
+
+                    // Check for overflow now
+                    for (int idx=0; idx < numBands; idx++){
+                        if (((int)newPixels[pixelIndex+idx] & masks[idx]) != 0) {
+                            if (newPixels[pixelIndex+idx] < 0) {
+                                newPixels[pixelIndex+idx] = 0;
+                            } else {
+                                newPixels[pixelIndex+idx] = maxValues[idx];
+                            }
+                        }
+                    }
+                }
+            }
+
+            dst.setPixels(dstMinX, dstMinY, srcWidth, srcHeight, newPixels);
+        } catch (Exception e) { // Something goes wrong, signal error
+            return 1;
+        }
+        return 0;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        if (src == null) {
+            // awt.259=Source image is null
+            throw new NullPointerException(Messages.getString("awt.259")); //$NON-NLS-1$
+        }
+
+        if (src == dst){
+            // awt.25A=Source equals to destination
+            throw new IllegalArgumentException(Messages.getString("awt.25A")); //$NON-NLS-1$
+        }
+
+        ColorModel srcCM = src.getColorModel();
+        BufferedImage finalDst = null;
+
+        if (srcCM instanceof IndexColorModel) {
+            src = ((IndexColorModel)srcCM).convertToIntDiscrete(src.getRaster(), true);
+            srcCM = src.getColorModel();
+        }
+
+        if (dst == null) {
+            dst = createCompatibleDestImage(src, srcCM);
+        } else {
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB as same
+                if (
+                        !((src.getType() == BufferedImage.TYPE_INT_RGB ||
+                           src.getType() == BufferedImage.TYPE_INT_ARGB) &&
+                          (dst.getType() == BufferedImage.TYPE_INT_RGB ||
+                           dst.getType() == BufferedImage.TYPE_INT_ARGB))
+                ) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, srcCM);
+                }
+            }
+        }
+
+        // Skip alpha channel for TYPE_INT_RGB images
+        // TODO
+        //if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) != 0)
+            if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private int ippFilter(Raster src, WritableRaster dst, int imageType) {
+        int srcStride, dstStride;
+        boolean skipChannel = false;
+        int channels;
+        int offsets[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_RGB:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                skipChannel = true;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in native code?
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1, 3 and 4 channels
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst);
+                    }
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride();
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                     // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (
+                            sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                            sppsm2.getDataType() != DataBuffer.TYPE_INT ||
+                            !(channels == 3 || channels == 4)
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst);
+                        }
+                    }
+
+                    if (channels == 3) { // Cannot skip channel, don't know which is alpha...
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        return ippFilter32f(
+            kernel.data, kernel.getWidth(), kernel.getHeight(),
+            kernel.getXOrigin(), kernel.getYOrigin(), edgeCond,
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            channels, skipChannel, offsets
+        );
+    }
+
+    /**
+     * Ipp filter32f.
+     * 
+     * @param kernel the kernel
+     * @param kWidth the k width
+     * @param kHeight the k height
+     * @param anchorX the anchor x
+     * @param anchorY the anchor y
+     * @param borderType the border type
+     * @param src the src
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dst the dst
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param channels the channels
+     * @param skipChannel the skip channel
+     * @param offsets the offsets
+     * 
+     * @return the int
+     */
+    private native int ippFilter32f(
+                float kernel[], int kWidth, int kHeight,
+                int anchorX, int anchorY, int borderType,
+                Object src, int srcWidth, int srcHeight, int srcStride,
+                Object dst, int dstWidth, int dstHeight, int dstStride,
+                int channels, boolean skipChannel, int offsets[]
+            );
+}
+
diff --git a/awt/java/awt/image/CropImageFilter.java b/awt/java/awt/image/CropImageFilter.java
new file mode 100644
index 0000000..e90c44a
--- /dev/null
+++ b/awt/java/awt/image/CropImageFilter.java
@@ -0,0 +1,193 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The CropImageFilter class crops a rectangular region of an source
+ * Image and provides a source for a new image containing the extracted 
+ * region.
+ */
+public class CropImageFilter extends ImageFilter {
+
+    /** The HEIGHT. */
+    private final int X, Y, WIDTH, HEIGHT;
+
+    /**
+     * Instantiates a new CropImageFilter object with the specified
+     * rectangular area.
+     * 
+     * @param x the X coordinate of rectangular area. 
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     */
+    public CropImageFilter(int x, int y, int w, int h) {
+        X = x;
+        Y = y;
+        WIDTH = w;
+        HEIGHT = h;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if(props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>) props.clone();
+        }
+        String propName = "Crop Filters"; //$NON-NLS-1$
+        String prop = "x=" + X + "; y=" + Y + "; width=" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        WIDTH + "; height=" + HEIGHT; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if(o != null){
+            if(o instanceof String){
+                prop = (String)o + "; " + prop; //$NON-NLS-1$
+            }else{
+                prop =  o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize) {
+
+        if(x + w < X || X + WIDTH < x ||
+                y + h < Y || Y + HEIGHT < y) {
+            return;
+        }
+
+        int destX, destY, destWidth, destHeight, endX, endY,
+        srcEndX, srcEndY;
+
+        int newOffset = off;
+
+        endX = X + WIDTH;
+        endY = Y + HEIGHT;
+
+        srcEndX = x + w;
+        srcEndY = y + h;
+
+        if(x <= X){
+            destX = 0;
+            newOffset += X;
+            if(endX >= srcEndX){
+                destWidth = srcEndX - X;
+            }else{
+                destWidth = WIDTH;
+            }
+        }else{
+            destX = x - X;
+            if(endX >= srcEndX){
+                destWidth = w;
+            }else{
+                destWidth = endX - x;
+            }
+        }
+
+
+        if(y <= Y){
+            newOffset += scansize * (Y - y);
+            destY = 0;
+            if(endY >= srcEndY){
+                destHeight = srcEndY - Y;
+            }else{
+                destHeight = HEIGHT;
+            }
+        }else{
+            destY = y - Y;
+            if(endY >= srcEndY){
+                destHeight = h;
+            }else{
+                destHeight = endY - y;
+            }
+        }
+        consumer.setPixels(destX, destY, destWidth, destHeight, model, pixels, newOffset, scansize);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize) {
+
+        if(x + w < X || X + WIDTH < x ||
+                y + h < Y || Y + HEIGHT < y) {
+            return;
+        }
+
+        int destX, destY, destWidth, destHeight, endX, endY,
+        srcEndX, srcEndY;
+
+        int newOffset = off;
+
+        endX = X + WIDTH;
+        endY = Y + HEIGHT;
+
+        srcEndX = x + w;
+        srcEndY = y + h;
+
+        if(x <= X){
+            destX = 0;
+            newOffset += X;
+            if(endX >= srcEndX){
+                destWidth = srcEndX - X;
+            }else{
+                destWidth = WIDTH;
+            }
+        }else{
+            destX = x - X;
+            if(endX >= srcEndX){
+                destWidth = w;
+            }else{
+                destWidth = endX - x;
+            }
+        }
+
+
+        if(y <= Y){
+            newOffset += scansize * (Y - y);
+            destY = 0;
+            if(endY >= srcEndY){
+                destHeight = srcEndY - Y;
+            }else{
+                destHeight = HEIGHT;
+            }
+        }else{
+            destY = y - Y;
+            if(endY >= srcEndY){
+                destHeight = h;
+            }else{
+                destHeight = endY - y;
+            }
+        }
+        consumer.setPixels(destX, destY, destWidth, destHeight, model, pixels, newOffset, scansize);
+    }
+
+    @Override
+    public void setDimensions(int w, int h) {
+        consumer.setDimensions(WIDTH, HEIGHT);
+    }
+
+}
+
diff --git a/awt/java/awt/image/DataBuffer.java b/awt/java/awt/image/DataBuffer.java
new file mode 100644
index 0000000..6856aee
--- /dev/null
+++ b/awt/java/awt/image/DataBuffer.java
@@ -0,0 +1,442 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DataBuffer is a wrapper class for a data array
+ * to be used for the situation where a suite of functionality
+ * acts on a set of data in a consistent way even though the 
+ * primitive type of the data may vary from one use to the next. 
+ */
+public abstract class DataBuffer {
+
+    /** The Constant TYPE_BYTE. */
+    public static final int TYPE_BYTE = 0;
+
+    /** The Constant TYPE_USHORT. */
+    public static final int TYPE_USHORT = 1;
+
+    /** The Constant TYPE_SHORT. */
+    public static final int TYPE_SHORT = 2;
+
+    /** The Constant TYPE_INT. */
+    public static final int TYPE_INT = 3;
+
+    /** The Constant TYPE_FLOAT. */
+    public static final int TYPE_FLOAT = 4;
+
+    /** The Constant TYPE_DOUBLE. */
+    public static final int TYPE_DOUBLE = 5;
+
+    /** The Constant TYPE_UNDEFINED. */
+    public static final int TYPE_UNDEFINED = 32;
+
+    /** The data type indicates the primitive type of the 
+     * data in this DataBuffer. */
+    protected int dataType;
+
+    /** The number of data arrays in this DataBuffer. */
+    protected int banks;
+
+    /** The starting index for reading the 
+     * data from the first (or only) internal data array. */
+    protected int offset;
+
+    /** The length (number of elements) of the data arrays. */
+    protected int size;
+
+    /** The starting indices for reading the 
+     * data from the internal data arrays. */
+    protected int offsets[];
+    
+    /** The data changed. */
+    boolean dataChanged = true;
+    
+    /** The data taken. */
+    boolean dataTaken = false;
+    
+    /** The listener. */
+    DataBufferListener listener;
+
+    static {
+        AwtImageBackdoorAccessorImpl.init();
+    }
+
+    /**
+     * Instantiates a new data buffer.
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     * @param numBanks the number of data arrays to create
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offsets = offsets.clone();
+        this.offset = offsets[0];
+    }
+
+    /**
+     * Instantiates a new data buffer with all of the 
+     * data arrays starting at the same index.
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     * @param numBanks the number of data arrays to create
+     * @param offset the offset to use for all of the data arrays
+     */
+    protected DataBuffer(int dataType, int size, int numBanks, int offset) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offset = offset;
+        this.offsets = new int[numBanks];
+        int i = 0;
+        while (i < numBanks) {
+            offsets[i++] = offset;
+        }
+    }
+
+    /**
+     * Instantiates a new data buffer with all of the 
+     * data arrays read from the beginning (at offset zero).
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    protected DataBuffer(int dataType, int size, int numBanks) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = numBanks;
+        this.offset = 0;
+        this.offsets = new int[numBanks];
+    }
+
+    /**
+     * Instantiates a new data buffer with one internal data array
+     * read from the beginning (at offset zero).
+     * 
+     * @param dataType the data type
+     * @param size the length (number of elements) of the data arrays
+     */
+    protected DataBuffer(int dataType, int size) {
+        this.dataType = dataType;
+        this.size = size;
+        this.banks = 1;
+        this.offset = 0;
+        this.offsets = new int[1];
+    }
+
+    /**
+     * Sets the data value in the specified array at the 
+     * specified index.
+     * 
+     * @param bank the internal array to the data to
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public abstract void setElem(int bank, int i, int val);
+
+    /**
+     * Sets the float data value in the specified array at the 
+     * specified index.
+     * 
+     * @param bank the internal array to the data to
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemFloat(int bank, int i, float val) {
+        setElem(bank, i, (int) val);
+    }
+
+    /**
+     * Sets the double data value in the specified array at the 
+     * specified index.
+     * 
+     * @param bank the internal array to the data to
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemDouble(int bank, int i, double val) {
+        setElem(bank, i, (int) val);
+    }
+
+    /**
+     * Sets the data value in the first array at the 
+     * specified index.
+     * 
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElem(int i, int val) {
+        setElem(0, i, val);
+    }
+
+    /**
+     * Gets the data value from the specified data array at the 
+     * specified index.
+     * 
+     * @param bank the data array to read from
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public abstract int getElem(int bank, int i);
+
+    /**
+     * Gets the float-type data value from the specified 
+     * data array at the specified index.
+     * 
+     * @param bank the data array to read from
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public float getElemFloat(int bank, int i) {
+        return getElem(bank, i);
+    }
+
+    /**
+     * Gets the double-type data value from the specified 
+     * data array at the specified index.
+     * 
+     * @param bank the data array to read from
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public double getElemDouble(int bank, int i) {
+        return getElem(bank, i);
+    }
+
+    /**
+     * Sets the float data value in the first array at the 
+     * specified index.
+     * 
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemFloat(int i, float val) {
+        setElemFloat(0, i, val);
+    }
+
+    /**
+     * Sets the double data value in the first array at the 
+     * specified index.
+     * 
+     * @param i the index within the array where the data
+     * should be written
+     * @param val the value to write into the array
+     */
+    public void setElemDouble(int i, double val) {
+        setElemDouble(0, i, val);
+    }
+
+    /**
+     * Gets the data value from the first 
+     * data array at the specified index and returns it
+     * as an int.
+     * 
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public int getElem(int i) {
+        return getElem(0, i);
+    }
+
+    /**
+     * Gets the data value from the first 
+     * data array at the specified index and returns it
+     * as a float.
+     * 
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public float getElemFloat(int i) {
+        return getElem(0, i);
+    }
+
+    /**
+     * Gets the data value from the first 
+     * data array at the specified index and returns it
+     * as a double.
+     * 
+     * @param i the index within the array where the data
+     * should be read
+     * 
+     * @return the data element
+     */
+    public double getElemDouble(int i) {
+        return getElem(i);
+    }
+
+    /**
+     * Gets the array giving the offsets corresponding 
+     * to the internal data arrays.
+     * 
+     * @return the array of offsets
+     */
+    public int[] getOffsets() {
+        return offsets;
+    }
+
+    /**
+     * Gets the size in bits of the primitive data type.
+     * 
+     * @return the size in bits of the primitive data type
+
+     */
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * Gets the offset corresponding to the first internal 
+     * data array.
+     * 
+     * @return the offset
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Gets the number of data arrays in this DataBuffer.
+     * 
+     * @return the number of data arrays
+     */
+    public int getNumBanks() {
+        return banks;
+    }
+
+    /**
+     * Gets the primitive type of this buffer's data.
+     * 
+     * @return the data type
+     */
+    public int getDataType() {
+        return this.dataType;
+    }
+
+    /**
+     * Gets the size in bits of the primitive data type.
+     * 
+     * @param type the primitive type
+     * 
+     * @return the size in bits of the primitive data type
+     */
+    public static int getDataTypeSize(int type) {
+        switch (type) {
+
+        case TYPE_BYTE:
+            return 8;
+
+        case TYPE_USHORT:
+        case TYPE_SHORT:
+            return 16;
+
+        case TYPE_INT:
+        case TYPE_FLOAT:
+            return 32;
+
+        case TYPE_DOUBLE:
+            return 64;
+
+        default:
+            // awt.22C=Unknown data type {0}
+            throw new IllegalArgumentException(Messages.getString("awt.22C", type)); //$NON-NLS-1$
+        }
+    }
+    
+    /**
+     * Notifies the listener that the data has changed.
+     */
+    void notifyChanged(){
+        if(listener != null && !dataChanged){
+            dataChanged = true;
+            listener.dataChanged();
+        }
+    }
+    
+    /**
+     * Notifies the listener that the data has been released.
+     */
+    void notifyTaken(){
+        if(listener != null && !dataTaken){
+            dataTaken = true;
+            listener.dataTaken();
+        }
+    }
+    
+    /**
+     * Release the data.
+     */
+    void releaseData(){
+        if(listener != null && dataTaken){
+            dataTaken = false;
+            listener.dataReleased();
+        }
+    }
+    
+    /**
+     * Adds the data buffer listener.
+     * 
+     * @param listener the listener
+     */
+    void addDataBufferListener(DataBufferListener listener){
+        this.listener = listener;
+    }
+    
+    /**
+     * Removes the data buffer listener.
+     */
+    void removeDataBufferListener(){
+        listener = null;
+    }
+    
+    /**
+     * Validate.
+     */
+    void validate(){
+        dataChanged = false;
+    }
+    
+}
+
diff --git a/awt/java/awt/image/DataBufferByte.java b/awt/java/awt/image/DataBufferByte.java
new file mode 100644
index 0000000..4d29c9c
--- /dev/null
+++ b/awt/java/awt/image/DataBufferByte.java
@@ -0,0 +1,171 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferByte is the subclass of DataBuffer
+ * for the case where the underlying data is of type byte.
+ */
+public final class DataBufferByte extends DataBuffer {
+
+    /** The data. */
+    byte data[][];
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferByte(byte dataArrays[][], int size, int offsets[]) {
+        super(TYPE_BYTE, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferByte(byte dataArrays[][], int size) {
+        super(TYPE_BYTE, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferByte(byte dataArray[], int size, int offset) {
+        super(TYPE_BYTE, size, 1, offset);
+        data = new byte[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferByte(byte dataArray[], int size) {
+        super(TYPE_BYTE, size);
+        data = new byte[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferByte(int size, int numBanks) {
+        super(TYPE_BYTE, size, numBanks);
+        data = new byte[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new byte[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferByte(int size) {
+        super(TYPE_BYTE, size);
+        data = new byte[1][];
+        data[0] = new byte[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (byte) val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (byte) val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]) & 0xff;
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public byte[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]) & 0xff;
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public byte[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public byte[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+
+}
+
diff --git a/awt/java/awt/image/DataBufferDouble.java b/awt/java/awt/image/DataBufferDouble.java
new file mode 100644
index 0000000..fa3d324
--- /dev/null
+++ b/awt/java/awt/image/DataBufferDouble.java
@@ -0,0 +1,214 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferDouble is the subclass of DataBuffer
+ * for the case where the underlying data is of type double.
+ */
+public final class DataBufferDouble extends DataBuffer {
+
+    /** The data. */
+    double data[][];
+
+    /**
+     * Instantiates a new data buffer of type double.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+    */
+    public DataBufferDouble(double dataArrays[][], int size, int offsets[]) {
+        super(TYPE_DOUBLE, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type double.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferDouble(double dataArrays[][], int size) {
+        super(TYPE_DOUBLE, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type double
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferDouble(double dataArray[], int size, int offset) {
+        super(TYPE_DOUBLE, size, 1, offset);
+        data = new double[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type double
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferDouble(double dataArray[], int size) {
+        super(TYPE_DOUBLE, size);
+        data = new double[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type double
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferDouble(int size, int numBanks) {
+        super(TYPE_DOUBLE, size, numBanks);
+        data = new double[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new double[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type double
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferDouble(int size) {
+        super(TYPE_DOUBLE, size);
+        data = new double[1][];
+        data[0] = new double[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemFloat(int bank, int i, float val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int bank, int i, double val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int) (data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public float getElemFloat(int bank, int i) {
+        return (float) (data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public double getElemDouble(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public void setElemFloat(int i, float val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int i, double val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public double[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (int) (data[0][offset + i]);
+    }
+
+    @Override
+    public float getElemFloat(int i) {
+        return (float) (data[0][offset + i]);
+    }
+
+    @Override
+    public double getElemDouble(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public double[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public double[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferFloat.java b/awt/java/awt/image/DataBufferFloat.java
new file mode 100644
index 0000000..e34245c
--- /dev/null
+++ b/awt/java/awt/image/DataBufferFloat.java
@@ -0,0 +1,214 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferFloat is the subclass of DataBuffer
+ * for the case where the underlying data is float.
+ */
+public final class DataBufferFloat extends DataBuffer {
+
+    /** The data. */
+    float data[][];
+
+    /**
+     * Instantiates a new data buffer of type float.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferFloat(float dataArrays[][], int size, int offsets[]) {
+        super(TYPE_FLOAT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type float.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferFloat(float dataArrays[][], int size) {
+        super(TYPE_FLOAT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type float
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferFloat(float dataArray[], int size, int offset) {
+        super(TYPE_FLOAT, size, 1, offset);
+        data = new float[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type float
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferFloat(float dataArray[], int size) {
+        super(TYPE_FLOAT, size);
+        data = new float[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type float
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferFloat(int size, int numBanks) {
+        super(TYPE_FLOAT, size, numBanks);
+        data = new float[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new float[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type float
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferFloat(int size) {
+        super(TYPE_FLOAT, size);
+        data = new float[1][];
+        data[0] = new float[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemFloat(int bank, int i, float val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int bank, int i, double val) {
+        data[bank][offsets[bank] + i] = (float) val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (int) (data[bank][offsets[bank] + i]);
+    }
+
+    @Override
+    public float getElemFloat(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public double getElemDouble(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    @Override
+    public void setElemFloat(int i, float val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElemDouble(int i, double val) {
+        data[0][offset + i] = (float) val;
+        notifyChanged();
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired array
+     * 
+     * @return the data
+     */
+    public float[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (int) (data[0][offset + i]);
+    }
+
+    @Override
+    public float getElemFloat(int i) {
+        return data[0][offset + i];
+    }
+
+    @Override
+    public double getElemDouble(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public float[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public float[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferInt.java b/awt/java/awt/image/DataBufferInt.java
new file mode 100644
index 0000000..43dc188
--- /dev/null
+++ b/awt/java/awt/image/DataBufferInt.java
@@ -0,0 +1,170 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferInt is the subclass of DataBuffer
+ * for the case where the underlying data is of type int.
+ */
+public final class DataBufferInt extends DataBuffer {
+
+    /** The data. */
+    int data[][];
+
+    /**
+     * Instantiates a new data buffer of type int.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferInt(int dataArrays[][], int size, int offsets[]) {
+        super(TYPE_INT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type int.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferInt(int dataArrays[][], int size) {
+        super(TYPE_INT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type int
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferInt(int dataArray[], int size, int offset) {
+        super(TYPE_INT, size, 1, offset);
+        data = new int[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type int
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferInt(int dataArray[], int size) {
+        super(TYPE_INT, size);
+        data = new int[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type int
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferInt(int size, int numBanks) {
+        super(TYPE_INT, size, numBanks);
+        data = new int[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new int[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type int
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferInt(int size) {
+        super(TYPE_INT, size);
+        data = new int[1][];
+        data[0] = new int[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return data[bank][offsets[bank] + i];
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public int[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return data[0][offset + i];
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public int[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public int[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferShort.java b/awt/java/awt/image/DataBufferShort.java
new file mode 100644
index 0000000..819ba4a
--- /dev/null
+++ b/awt/java/awt/image/DataBufferShort.java
@@ -0,0 +1,172 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+/**
+ * The Class DataBufferShort is the subclass of DataBuffer
+ * for the case where the underlying data is short.
+ */
+public final class DataBufferShort extends DataBuffer {
+
+    /** The data. */
+    short data[][];
+
+    /**
+     * Instantiates a new data buffer of type short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferShort(short dataArrays[][], int size, int offsets[]) {
+        super(TYPE_SHORT, size, dataArrays.length, offsets);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferShort(short dataArrays[][], int size) {
+        super(TYPE_SHORT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type short
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+
+     */
+    public DataBufferShort(short dataArray[], int size, int offset) {
+        super(TYPE_SHORT, size, 1, offset);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+
+     */
+    public DataBufferShort(short dataArray[], int size) {
+        super(TYPE_SHORT, size);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type short
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferShort(int size, int numBanks) {
+        super(TYPE_SHORT, size, numBanks);
+        data = new short[numBanks][];
+        int i = 0;
+        while (i < numBanks) {
+            data[i++] = new short[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferShort(int size) {
+        super(TYPE_SHORT, size);
+        data = new short[1][];
+        data[0] = new short[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (short) val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (short) val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]);
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public short[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]);
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public short[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public short[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DataBufferUShort.java b/awt/java/awt/image/DataBufferUShort.java
new file mode 100644
index 0000000..7982678
--- /dev/null
+++ b/awt/java/awt/image/DataBufferUShort.java
@@ -0,0 +1,182 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DataBufferUShort is the subclass of DataBuffer
+ * for the case where the underlying data is unsigned short.
+ */
+public final class DataBufferUShort extends DataBuffer {
+
+    /** The data. */
+    short data[][];
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param offsets the starting indices for reading the 
+     * data from the internal data arrays
+     */
+    public DataBufferUShort(short dataArrays[][], int size, int offsets[]) {
+        super(TYPE_USHORT, size, dataArrays.length, offsets);
+        for(int i = 0; i < dataArrays.length; i++){
+            if(dataArrays[i].length < offsets[i] + size){
+                // awt.28d=Length of dataArray[{0}] is less than size + offset[{1}]
+                throw new IllegalArgumentException(Messages.getString("awt.28D", i, i));  //$NON-NLS-1$
+            }
+        }
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short.
+     * 
+     * @param dataArrays the data arrays to copy the data from
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     */
+    public DataBufferUShort(short dataArrays[][], int size) {
+        super(TYPE_USHORT, size, dataArrays.length);
+        data = dataArrays.clone();
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     * @param offset the starting index to use when reading the data
+     */
+    public DataBufferUShort(short dataArray[], int size, int offset) {
+        super(TYPE_USHORT, size, 1, offset);
+        if(dataArray.length < size + offset){
+            // awt.28E=Length of dataArray is less than size + offset
+            throw new IllegalArgumentException(Messages.getString("awt.28E")); //$NON-NLS-1$
+        }
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param dataArray the data array to copy the data from
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferUShort(short dataArray[], int size) {
+        super(TYPE_USHORT, size);
+        data = new short[1][];
+        data[0] = dataArray;
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with offsets equal to zero.
+     * 
+     * @param size the length (number of elements) to use 
+     * from the data arrays
+     * @param numBanks the number of data arrays to create
+     */
+    public DataBufferUShort(int size, int numBanks) {
+        super(TYPE_USHORT, size, numBanks);
+        data = new short[numBanks][];
+        int i= 0;
+        while( i < numBanks) {
+            data[i++] = new short[size];
+        }
+    }
+
+    /**
+     * Instantiates a new empty data buffer of type unsigned short
+     * with a single underlying array of data starting at
+     * index 0.
+     * 
+     * @param size the length (number of elements) to use 
+     */
+    public DataBufferUShort(int size) {
+        super(TYPE_USHORT, size);
+        data = new short[1][];
+        data[0] = new short[size];
+    }
+
+    @Override
+    public void setElem(int bank, int i, int val) {
+        data[bank][offsets[bank] + i] = (short)val;
+        notifyChanged();
+    }
+
+    @Override
+    public void setElem(int i, int val) {
+        data[0][offset + i] = (short)val;
+        notifyChanged();
+    }
+
+    @Override
+    public int getElem(int bank, int i) {
+        return (data[bank][offsets[bank] + i]) & 0xffff;
+    }
+
+    /**
+     * Gets the data of the specified internal data array.
+     * 
+     * @param bank the index of the desired data array
+     * 
+     * @return the data
+     */
+    public short[] getData(int bank) {
+        notifyTaken();
+        return data[bank];
+    }
+
+    @Override
+    public int getElem(int i) {
+        return (data[0][offset + i]) & 0xffff;
+    }
+
+    /**
+     * Gets the bank data.
+     * 
+     * @return the bank data
+     */
+    public short[][] getBankData() {
+        notifyTaken();
+        return data.clone();
+    }
+
+    /**
+     * Gets the data of the first data array.
+     * 
+     * @return the data
+     */
+    public short[] getData() {
+        notifyTaken();
+        return data[0];
+    }
+}
+
diff --git a/awt/java/awt/image/DirectColorModel.java b/awt/java/awt/image/DirectColorModel.java
new file mode 100644
index 0000000..7a287c0
--- /dev/null
+++ b/awt/java/awt/image/DirectColorModel.java
@@ -0,0 +1,862 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.color.ColorSpace;
+import java.awt.Transparency;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class DirectColorModel represents a standard (packed) RGB
+ * color model with additional support for converting between sRGB
+ * color space and 8 or 16 bit linear RGB color space using lookup tables.
+ */
+public class DirectColorModel extends PackedColorModel {
+
+    /** The from_ linea r_ rg b_ lut. */
+    private byte from_LINEAR_RGB_LUT[]; // Lookup table for conversion from
+                                        // Linear RGB Color Space into sRGB
+
+    /** The to_ linea r_8 rg b_ lut. */
+    private byte to_LINEAR_8RGB_LUT[];  // Lookup table for conversion from
+                                        // sRGB Color Space into Linear RGB 
+                                        // 8 bit
+
+    /** The to_ linea r_16 rg b_ lut. */
+    private short to_LINEAR_16RGB_LUT[];  // Lookup table for conversion from
+                                          // sRGB Color Space into Linear RGB 
+                                          // 16 bit 
+
+    /** The alpha lut. */
+    private byte alphaLUT[];            // Lookup table for scale alpha value  
+
+    /** The color lu ts. */
+    private byte colorLUTs[][];         // Lookup tables for scale color values 
+
+    /** The is_s rgb. */
+    private boolean is_sRGB;            // ColorModel has sRGB ColorSpace
+
+    /** The is_ linea r_ rgb. */
+    private boolean is_LINEAR_RGB;      // Color Model has Linear RGB Color 
+                                        // Space
+
+    /** The LINEA r_ rg b_ length. */
+    private int LINEAR_RGB_Length;      // Linear RGB bit length
+
+    /** The factor. */
+    private float fFactor;              // Scale factor
+
+    /**
+     * Instantiates a new direct color model.
+     * 
+     * @param space the color space
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     * @param amask the bitmask corresponding to the alpha band
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this color model
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the number of bits in the combined 
+     * bitmasks for the color bands is less than one or greater than 32
+     */
+    public DirectColorModel(ColorSpace space, int bits, int rmask, int gmask,
+            int bmask, int amask, boolean isAlphaPremultiplied,
+            int transferType) {
+
+        super(space, bits, rmask, gmask, bmask, amask, isAlphaPremultiplied,
+                (amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
+                transferType);
+
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new direct color model, determining the transfer 
+     * type from the bits array, the transparency from the alpha mask, 
+     * and the default color space {@link ColorSpace#CS_sRGB}.
+     * 
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     * @param amask the bitmask corresponding to the alpha band
+     */
+    public DirectColorModel(int bits, int rmask, int gmask, int bmask,
+            int amask) {
+
+        super(ColorSpace.getInstance(ColorSpace.CS_sRGB), bits, rmask, gmask,
+                bmask, amask, false,
+                (amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
+                ColorModel.getTransferType(bits));
+
+        initLUTs();
+    }
+
+    /**
+     * Instantiates a new direct color model with no alpha channel, 
+     * determining the transfer type from the bits array, 
+     * the default color space {@link ColorSpace#CS_sRGB}, 
+     * and with the transparency set to {@link Transparency#OPAQUE}.
+     * 
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     */
+    public DirectColorModel(int bits, int rmask, int gmask, int bmask) {
+        this(bits, rmask, gmask, bmask, 0);
+    }
+
+    @Override
+    public Object getDataElements(int components[], int offset, Object obj) {
+        int pixel = 0;
+        for (int i = 0; i < numComponents; i++) {
+            pixel |= (components[offset + i] << offsets[i]) & componentMasks[i];
+        }
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (obj == null) {
+                ba = new byte[1];
+            } else {
+                ba = (byte[]) obj;
+            }
+            ba[0] = (byte) pixel;
+            obj = ba;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[];
+            if (obj == null) {
+                sa = new short[1];
+            } else {
+                sa = (short[]) obj;
+            }
+            sa[0] = (short) pixel;
+            obj = sa;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (obj == null) {
+                ia = new int[1];
+            } else {
+                ia = (int[]) obj;
+            }
+            ia[0] = pixel;
+            obj = ia;
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+
+        return obj;
+    }
+
+    @Override
+    public Object getDataElements(int rgb, Object pixel) {
+        if (equals(ColorModel.getRGBdefault())) {
+            int ia[];
+            if (pixel == null) {
+                ia = new int[1];
+            } else {
+                ia = (int[]) pixel;
+            }
+            ia[0] = rgb;
+            return ia;
+        }
+
+        int alpha = (rgb >> 24) & 0xff;
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+
+        float comp[] = new float[numColorComponents];
+        float normComp[] = null;
+
+        if (is_sRGB || is_LINEAR_RGB) {
+            if (is_LINEAR_RGB) {
+                if (LINEAR_RGB_Length == 8) {
+                    red = to_LINEAR_8RGB_LUT[red] & 0xff;
+                    green = to_LINEAR_8RGB_LUT[green] & 0xff;
+                    blue = to_LINEAR_8RGB_LUT[blue] & 0xff;
+                } else {
+                    red = to_LINEAR_16RGB_LUT[red] & 0xffff;
+                    green = to_LINEAR_16RGB_LUT[green] & 0xffff;
+                    blue = to_LINEAR_16RGB_LUT[blue] & 0xffff;
+                }
+            }
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            if (!hasAlpha) {
+                normComp = comp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = comp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        } else {
+            comp[0] = red / fFactor;
+            comp[1] = green / fFactor;
+            comp[2] = blue / fFactor;
+            float rgbComp[] = cs.fromRGB(comp);
+            if (!hasAlpha) {
+                normComp = rgbComp;
+            } else {
+                float normAlpha = alpha / 255.0f;
+                normComp = new float[numComponents];
+                for (int i = 0; i < numColorComponents; i++) {
+                    normComp[i] = rgbComp[i];
+                }
+                normComp[numColorComponents] = normAlpha;
+            }
+        }
+
+        int pxl = 0;
+        if (hasAlpha) {
+            float normAlpha = normComp[numColorComponents];
+            alpha = (int) (normAlpha * maxValues[numColorComponents] + 0.5f);
+            if (isAlphaPremultiplied) {
+                red = (int) (normComp[0] * normAlpha * maxValues[0] + 0.5f);
+                green = (int) (normComp[1] * normAlpha * maxValues[1] + 0.5f);
+                blue = (int) (normComp[2] * normAlpha * maxValues[2] + 0.5f);
+            } else {
+                red = (int) (normComp[0] * maxValues[0] + 0.5f);
+                green = (int) (normComp[1] * maxValues[1] + 0.5f);
+                blue = (int) (normComp[2] * maxValues[2] + 0.5f);
+            }
+            pxl = (alpha << offsets[3]) & componentMasks[3];
+        } else {
+            red = (int) (normComp[0] * maxValues[0] + 0.5f);
+            green = (int) (normComp[1] * maxValues[1] + 0.5f);
+            blue = (int) (normComp[2] * maxValues[2] + 0.5f);
+        }
+
+        pxl |= ((red << offsets[0]) & componentMasks[0]) |
+               ((green << offsets[1]) & componentMasks[1]) |
+               ((blue << offsets[2]) & componentMasks[2]);
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[];
+            if (pixel == null) {
+                ba = new byte[1];
+            } else {
+                ba = (byte[]) pixel;
+            }
+            ba[0] = (byte) pxl;
+            return ba;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[];
+            if (pixel == null) {
+                sa = new short[1];
+            } else {
+                sa = (short[]) pixel;
+            }
+            sa[0] = (short) pxl;
+            return sa;
+
+        case DataBuffer.TYPE_INT:
+            int ia[];
+            if (pixel == null) {
+                ia = new int[1];
+            } else {
+                ia = (int[]) pixel;
+            }
+            ia[0] = pxl;
+            return ia;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public final ColorModel coerceData(WritableRaster raster,
+            boolean isAlphaPremultiplied) {
+
+        if (!hasAlpha || this.isAlphaPremultiplied == isAlphaPremultiplied) {
+            return this;
+        }
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        int components[] = null;
+        int transparentComponents[] = new int[numComponents];
+
+        float alphaFactor = maxValues[numColorComponents];
+
+        if (isAlphaPremultiplied) {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        components = raster.getPixel(x, minY, components);
+                        if (components[numColorComponents] == 0) {
+                            raster.setPixel(x, minY, transparentComponents);
+                        } else {
+                            float alpha =
+                                components[numColorComponents] /
+                                    alphaFactor;
+                            for (int n = 0; n < numColorComponents; n++) {
+                                components[n] =
+                                    (int) (alpha * components[n] + 0.5f);
+                            }
+                            raster.setPixel(x, minY, components);
+                        }
+                    }
+
+                }
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+            }
+        } else {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+            case DataBuffer.TYPE_USHORT:
+            case DataBuffer.TYPE_INT:
+                for (int i = 0; i < h; i++, minY++) {
+                    for (int j = 0, x = minX; j < w; j++, x++) {
+                        components = raster.getPixel(x, minY, components);
+                        if (components[numColorComponents] != 0) {
+                            float alpha =
+                                alphaFactor / components[numColorComponents];
+                            for (int n = 0; n < numColorComponents; n++) {
+                                components[n] =
+                                    (int) (alpha * components[n] + 0.5f);
+                            }
+                            raster.setPixel(x, minY, components);
+                        }
+                    }
+
+                }
+                break;
+
+            default:
+                // awt.214=This Color Model doesn't support this transferType
+                throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+            }
+
+        }
+
+        return new DirectColorModel(cs, pixel_bits, componentMasks[0],
+                componentMasks[1], componentMasks[2], componentMasks[3],
+                isAlphaPremultiplied, transferType);
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. 
+        // It could be reveled such way:
+        // BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
+        // ColorModel cm = bi.getColorModel();
+        // System.out.println(cm.toString());
+        String str = "DirectColorModel:" + " rmask = " + //$NON-NLS-1$ //$NON-NLS-2$
+               Integer.toHexString(componentMasks[0]) + " gmask = " + //$NON-NLS-1$
+               Integer.toHexString(componentMasks[1]) + " bmask = " + //$NON-NLS-1$
+               Integer.toHexString(componentMasks[2]) + " amask = " + //$NON-NLS-1$
+               (!hasAlpha ? "0" : Integer.toHexString(componentMasks[3])); //$NON-NLS-1$
+
+        return str;
+    }
+
+    @Override
+    public final int[] getComponents(Object pixel, int components[],
+            int offset) {
+
+        if (components == null) {
+            components = new int[numComponents + offset];
+        }
+
+        int intPixel = 0;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) pixel;
+            intPixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) pixel;
+            intPixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) pixel;
+            intPixel = ia[0];
+            break;
+
+        default:
+            // awt.22D=This transferType ( {0} ) is not supported by this color model
+            throw new UnsupportedOperationException(Messages.getString("awt.22D", //$NON-NLS-1$
+                   transferType));
+        }
+
+        return getComponents(intPixel, components, offset);
+    }
+
+    @Override
+    public int getRed(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getRed(pixel);
+    }
+
+    @Override
+    public int getRGB(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getRGB(pixel);
+    }
+
+    @Override
+    public int getGreen(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getGreen(pixel);
+    }
+
+    @Override
+    public int getBlue(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getBlue(pixel);
+    }
+
+    @Override
+    public int getAlpha(Object inData) {
+        int pixel = 0;
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) inData;
+            pixel = ba[0] & 0xff;
+            break;
+
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) inData;
+            pixel = sa[0] & 0xffff;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ia[] = (int[]) inData;
+            pixel = ia[0];
+            break;
+
+        default:
+            // awt.214=This Color Model doesn't support this transferType
+            throw new UnsupportedOperationException(Messages.getString("awt.214")); //$NON-NLS-1$
+        }
+        return getAlpha(pixel);
+    }
+
+    @Override
+    public final WritableRaster createCompatibleWritableRaster(int w, int h) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        int bandMasks[] = componentMasks.clone();
+
+        if (pixel_bits > 16) {
+            return Raster.createPackedRaster(DataBuffer.TYPE_INT, w, h,
+                    bandMasks, null);
+        } else if (pixel_bits > 8) {
+            return Raster.createPackedRaster(DataBuffer.TYPE_USHORT, w, h,
+                    bandMasks, null);
+        } else {
+            return Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h,
+                    bandMasks, null);
+        }
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        SampleModel sm = raster.getSampleModel();
+        if (!(sm instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+
+        SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+
+        if (sppsm.getNumBands() != numComponents) {
+            return false;
+        }
+        if (raster.getTransferType() != transferType) {
+            return false;
+        }
+
+        int maskBands[] = sppsm.getBitMasks();
+        return Arrays.equals(maskBands, componentMasks);
+    }
+
+    @Override
+    public int getDataElement(int components[], int offset) {
+        int pixel = 0;
+        for (int i = 0; i < numComponents; i++) {
+            pixel |= (components[offset + i] << offsets[i]) & componentMasks[i];
+        }
+        return pixel;
+    }
+
+    @Override
+    public final int[] getComponents(int pixel, int components[], int offset) {
+        if (components == null) {
+            components = new int[numComponents + offset];
+        }
+        for (int i = 0; i < numComponents; i++) {
+            components[offset + i] = (pixel & componentMasks[i]) >> offsets[i];
+        }
+        return components;
+    }
+
+    @Override
+    public final int getRed(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 0);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 0);
+        }
+        return getComponentFrom_RGB(pixel, 0);
+    }
+
+    @Override
+    public final int getRGB(int pixel) {
+        return (getAlpha(pixel) << 24) | (getRed(pixel) << 16) |
+               (getGreen(pixel) << 8) | getBlue(pixel);
+    }
+
+    @Override
+    public final int getGreen(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 1);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 1);
+        }
+        return getComponentFrom_RGB(pixel, 1);
+    }
+
+    @Override
+    public final int getBlue(int pixel) {
+        if (is_sRGB) {
+            return getComponentFrom_sRGB(pixel, 2);
+        }
+        if (is_LINEAR_RGB) {
+            return getComponentFrom_LINEAR_RGB(pixel, 2);
+        }
+        return getComponentFrom_RGB(pixel, 2);
+    }
+
+    @Override
+    public final int getAlpha(int pixel) {
+        if (!hasAlpha) {
+            return 255;
+        }
+        int a = (pixel & componentMasks[3]) >>> offsets[3];
+        if (bits[3] == 8) {
+            return a;
+        }
+        return alphaLUT[a] & 0xff;
+    }
+
+    /**
+     * Gets the red mask.
+     * 
+     * @return the red mask
+     */
+    public final int getRedMask() {
+        return componentMasks[0];
+    }
+
+    /**
+     * Gets the green mask.
+     * 
+     * @return the green mask
+     */
+    public final int getGreenMask() {
+        return componentMasks[1];
+    }
+
+    /**
+     * Gets the blue mask.
+     * 
+     * @return the blue mask
+     */
+    public final int getBlueMask() {
+        return componentMasks[2];
+    }
+
+    /**
+     * Gets the alpha mask.
+     * 
+     * @return the alpha mask
+     */
+    public final int getAlphaMask() {
+        if (hasAlpha) {
+            return componentMasks[3];
+        }
+        return 0;
+    }
+
+    /**
+     * Initialization of Lookup tables.
+     */
+    private void initLUTs() {
+        is_sRGB = cs.isCS_sRGB();
+        is_LINEAR_RGB = (cs == LUTColorConverter.LINEAR_RGB_CS);
+
+        if (is_LINEAR_RGB) {
+            if (maxBitLength > 8) {
+                LINEAR_RGB_Length = 16;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom16lRGBtosRGB_LUT();
+                to_LINEAR_16RGB_LUT =
+                    LUTColorConverter.getFromsRGBto16lRGB_LUT();
+            } else {
+                LINEAR_RGB_Length = 8;
+                from_LINEAR_RGB_LUT =
+                    LUTColorConverter.getFrom8lRGBtosRGB_LUT();
+                to_LINEAR_8RGB_LUT =
+                    LUTColorConverter.getFromsRGBto8lRGB_LUT();
+            }
+            fFactor = ((1 << LINEAR_RGB_Length) - 1);
+        } else {
+            fFactor = 255.0f;
+        }
+
+        if (hasAlpha && bits[3] != 8) {
+            alphaLUT = new byte[maxValues[3] + 1];
+            for (int i = 0; i <= maxValues[3]; i++) {
+                alphaLUT[i] = (byte) (scales[3] * i + 0.5f);
+            }
+
+        }
+
+        if (!isAlphaPremultiplied) {
+            colorLUTs = new byte[3][];
+
+            if (is_sRGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != 8) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[i]; j++) {
+                            colorLUTs[i][j] = (byte) (scales[i] * j + 0.5f);
+                        }
+                    }
+                }
+            }
+
+            if (is_LINEAR_RGB) {
+                for (int i = 0; i < numColorComponents; i++) {
+                    if (bits[i] != LINEAR_RGB_Length) {
+                        for (int j = 0; j < i; j++) {
+                            if (bits[i] == bits[j]) {
+                                colorLUTs[i] = colorLUTs[j];
+                                break;
+                            }
+                        }
+                        colorLUTs[i] = new byte[maxValues[i] + 1];
+                        for (int j = 0; j <= maxValues[0]; j++) {
+                            int idx;
+                            if (LINEAR_RGB_Length == 8) {
+                                idx = (int) (scales[i] * j + 0.5f);
+                            } else {
+                                idx = (int) (scales[i] * j * 257.0f + 0.5f);
+                            }
+                            colorLUTs[i][j] = from_LINEAR_RGB_LUT[idx];
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+    /**
+     * This method return RGB component value if Color Model has
+     * sRGB ColorSpace.
+     * 
+     * @param pixel - INT representation of pixel
+     * @param idx - index of pixel component
+     * 
+     * @return - value of the pixel component scaled fro 0 to 255
+     */
+    private int getComponentFrom_sRGB(int pixel, int idx) {
+        int comp = (pixel & componentMasks[idx]) >> offsets[idx];
+        if (isAlphaPremultiplied) {
+            int alpha = (pixel & componentMasks[3]) >>> offsets[3];
+            comp = alpha == 0 ? 0 : (int) (scales[idx] * comp * 255.0f /
+                    (scales[3] * alpha) + 0.5f);
+        } else if (bits[idx] != 8) {
+            comp = colorLUTs[idx][comp] & 0xff;
+        }
+        return comp;
+    }
+
+    /**
+     * This method return RGB component value if Color Model has
+     * Linear RGB ColorSpace.
+     * 
+     * @param pixel - INT representation of pixel
+     * @param idx - index of pixel component
+     * 
+     * @return - value of the pixel component scaled fro 0 to 255
+     */
+    private int getComponentFrom_LINEAR_RGB(int pixel, int idx) {
+        int comp = (pixel & componentMasks[idx]) >> offsets[idx];
+        if (isAlphaPremultiplied) {
+            float factor = ((1 << LINEAR_RGB_Length) - 1);
+            int alpha = (pixel & componentMasks[3]) >> offsets[3];
+            comp = alpha == 0 ? 0 : (int) (scales[idx] * comp * factor /
+                    (scales[3] * alpha) + 0.5f);
+        } else if (bits[idx] != LINEAR_RGB_Length) {
+            comp = colorLUTs[idx][comp] & 0xff;
+        } else {
+            comp = from_LINEAR_RGB_LUT[comp] & 0xff;
+        }
+        return comp;
+    }
+
+    /**
+     * This method return RGB component value if Color Model has
+     * arbitrary RGB ColorSapce.
+     * 
+     * @param pixel - INT representation of pixel
+     * @param idx - index of pixel component
+     * 
+     * @return - value of the pixel component scaled fro 0 to 255
+     */
+    private int getComponentFrom_RGB(int pixel, int idx) {
+        int components[] = getComponents(pixel, null, 0);
+        float[] normComponents = getNormalizedComponents(components, 0, null, 0);
+        float[] sRGBcomponents = cs.toRGB(normComponents);
+        return (int) (sRGBcomponents[idx] * 255.0f + 0.5f);
+    }
+
+}
+
diff --git a/awt/java/awt/image/FilteredImageSource.java b/awt/java/awt/image/FilteredImageSource.java
new file mode 100644
index 0000000..6a41fa7
--- /dev/null
+++ b/awt/java/awt/image/FilteredImageSource.java
@@ -0,0 +1,88 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+
+/**
+ * The FilteredImageSource class is used for producing image data for a new 
+ * filtered version of the original image using the specified filter object. 
+ */
+public class FilteredImageSource implements ImageProducer {
+
+    /** The source. */
+    private final ImageProducer source;
+    
+    /** The filter. */
+    private final ImageFilter filter;
+
+    /** The cons table. */
+    private final Hashtable<ImageConsumer, ImageConsumer> consTable = new Hashtable<ImageConsumer, ImageConsumer>();
+
+    /**
+     * Instantiates a new FilteredImageSource object with 
+     * the specified ImageProducer and the ImageFilter objects.
+     * 
+     * @param orig the specified ImageProducer.
+     * @param imgf the specified ImageFilter.
+     */
+    public FilteredImageSource(ImageProducer orig, ImageFilter imgf) {
+        source = orig;
+        filter = imgf;
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        if(ic != null) {
+            return consTable.containsKey(ic);
+        }
+        return false;
+    }
+
+    public void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+        ImageConsumer fic = consTable.get(ic);
+        source.startProduction(fic);
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+        if(ic != null && isConsumer(ic)){
+            ImageFilter fic = (ImageFilter) consTable.get(ic);
+            fic.resendTopDownLeftRight(source);
+        }
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        if(ic != null && isConsumer(ic)){
+            ImageConsumer fic = consTable.get(ic);
+            source.removeConsumer(fic);
+            consTable.remove(ic);
+        }
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if(ic != null && !isConsumer(ic)){
+            ImageConsumer fic = filter.getFilterInstance(ic);
+            source.addConsumer(fic);
+            consTable.put(ic, fic);
+        }
+    }
+}
diff --git a/awt/java/awt/image/ImageConsumer.java b/awt/java/awt/image/ImageConsumer.java
new file mode 100644
index 0000000..2eba290
--- /dev/null
+++ b/awt/java/awt/image/ImageConsumer.java
@@ -0,0 +1,165 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The ImageConsumer interface provides the data about the image
+ * and about how its data is delivered.  A ImageProducer provides 
+ * all of the information about the image using 
+ * the methods defined in this interface.
+ */
+public interface ImageConsumer {
+
+    /** 
+     * The Constant RANDOMPIXELORDER indicates that the pixels are 
+     * delivered in a random order.
+     */
+    public static final int RANDOMPIXELORDER = 1;
+
+    /** 
+     * The Constant TOPDOWNLEFTRIGHT indicates that the pixels are 
+     * delivered in top-down, left-to-right order. 
+     */
+    public static final int TOPDOWNLEFTRIGHT = 2;
+
+    /** 
+     * The Constant COMPLETESCANLINES indicates that the pixels are
+     * delivered in complete scanline. 
+     */
+    public static final int COMPLETESCANLINES = 4;
+
+    /** 
+     * The Constant SINGLEPASS indicates that pixels are delivered 
+     * in a single pass. 
+     */
+    public static final int SINGLEPASS = 8;
+
+    /** 
+     * The Constant SINGLEFRAME indicates that image consists of
+     * single frame.
+     */
+    public static final int SINGLEFRAME = 16;
+
+    /** 
+     * The Constant IMAGEERROR indicates an image error during image producing.
+     */
+    public static final int IMAGEERROR = 1;
+
+    /** 
+     * The Constant SINGLEFRAMEDONE indicates that only one of the 
+     * image's frames is completed. 
+     */
+    public static final int SINGLEFRAMEDONE = 2;
+
+    /** 
+     * The Constant STATICIMAGEDONE indicates that the image is completed. 
+     */
+    public static final int STATICIMAGEDONE = 3;
+
+    /** 
+     * The Constant IMAGEABORTED indicates that the image producing 
+     * process is aborted. 
+     */
+    public static final int IMAGEABORTED = 4;
+
+    /**
+     * Sets the properties for the image associated with this ImageConsumer.
+     * 
+     * @param props the properties for the image associated with 
+     * this ImageConsumer.
+     */
+    public void setProperties(Hashtable<?, ?> props);
+
+    /**
+     * Sets the ColorModel object.
+     * 
+     * @param model the new ColorModel.
+     */
+    public void setColorModel(ColorModel model);
+
+    /**
+     * Sets the pixels for the specified rectangular area of the image.
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param model the specified ColorModel to be used for pixels
+     * converting.  
+     * @param pixels the array of pixels.
+     * @param off the offset of pixels array.
+     * @param scansize the distance from the one row of pixels
+     * to the next row in the specified array.
+     */
+    public void setPixels(int x, int y, int w, int h, ColorModel model,
+            int[] pixels, int off, int scansize);
+
+    /**
+     * Sets the pixels for the specified rectangular area of the image.
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param model the specified ColorModel to be used for pixels
+     * converting.  
+     * @param pixels the array of pixels.
+     * @param off the offset of pixels array.
+     * @param scansize the distance from the one row of pixels
+     * to the next row in the specified array.
+     */
+    public void setPixels(int x, int y, int w, int h, ColorModel model,
+            byte[] pixels, int off, int scansize);
+
+    /**
+     * Sets the dimensions of a source image.
+     * 
+     * @param width the width of the image.
+     * @param height the height of the image.
+     */
+    public void setDimensions(int width, int height);
+
+    /**
+     * Sets the hint flags of pixels order, which is used by 
+     * the ImageConsumer for obtaining pixels from the ImageProducer
+     * for which this ImageConsumer is added.
+     * 
+     * @param hintflags the mask of hint flags. 
+     */
+    public void setHints(int hintflags);
+
+    /**
+     * THis method is called in the one of the following cases:
+     * <ul>
+     * <li>The ImageProducer (for which this ImageConsumer is added) 
+     * has been delivered all pixels of the source image. </li>
+     * <li>A one frame of an animation has been completed. </li> 
+     * <li> An error while loading or producing of the image has occured.
+     * </ul> 
+     * 
+     * @param status the status of image producing.
+     */
+    public void imageComplete(int status);
+
+}
+
diff --git a/awt/java/awt/image/ImageFilter.java b/awt/java/awt/image/ImageFilter.java
new file mode 100644
index 0000000..e386d65
--- /dev/null
+++ b/awt/java/awt/image/ImageFilter.java
@@ -0,0 +1,129 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+/**
+ * The ImageFilter class provides a filter for delivering image data 
+ * from an ImageProducer to an ImageConsumer.
+ */
+public class ImageFilter implements ImageConsumer, Cloneable {
+
+    /** The consumer. */
+    protected ImageConsumer consumer;
+
+    /**
+     * Instantiates a new ImageFilter.
+     */
+    public ImageFilter() {
+        super();
+    }
+
+    /**
+     * Gets an instance of an ImageFilter object which performs
+     * the filtering for the specified ImageConsumer.
+     *  
+     * @param ic the specified ImageConsumer.
+     * 
+     * @return an ImageFilter used to perform the filtering for 
+     * the specified ImageConsumer.
+     */
+    public ImageFilter getFilterInstance(ImageConsumer ic) {
+        ImageFilter filter = (ImageFilter) clone();
+        filter.consumer = ic;
+        return filter;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if (props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>) props.clone();
+        }
+        String propName = "Filters"; //$NON-NLS-1$
+        String prop = "Null filter"; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if (o != null) {
+            if (o instanceof String) {
+                prop = (String) o + "; " + prop; //$NON-NLS-1$
+            } else {
+                prop = o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+    }
+
+    /**
+     * Returns a copy of this ImageFilter.
+     * 
+     * @return a copy of this ImageFilter.
+     */
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Responds to a request for a Top-Down-Left-Right ordered 
+     * resend of the pixel data from an ImageConsumer. 
+     * 
+     * @param ip the ImageProducer that provides this instance of 
+     * the filter.
+     */
+    public void resendTopDownLeftRight(ImageProducer ip) {
+        ip.requestTopDownLeftRightResend(this);
+    }
+
+    public void setColorModel(ColorModel model) {
+        consumer.setColorModel(model);
+    }
+
+    public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off,
+            int scansize) {
+        consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
+    }
+
+    public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off,
+            int scansize) {
+        consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
+    }
+
+    public void setDimensions(int width, int height) {
+        consumer.setDimensions(width, height);
+    }
+
+    public void setHints(int hints) {
+        consumer.setHints(hints);
+    }
+
+    public void imageComplete(int status) {
+        consumer.imageComplete(status);
+    }
+
+}
diff --git a/awt/java/awt/image/ImageObserver.java b/awt/java/awt/image/ImageObserver.java
new file mode 100644
index 0000000..418bd07
--- /dev/null
+++ b/awt/java/awt/image/ImageObserver.java
@@ -0,0 +1,99 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Image;
+
+/**
+ * the ImageObserver interface is an asynchronous update interface 
+ * for receiving notifications about Image construction status.
+ */
+public interface ImageObserver {
+
+    /** 
+     * The Constant WIDTH indicates that the width of the image is 
+     * available. 
+     */
+    public static final int WIDTH = 1;
+
+    /** 
+     * The Constant HEIGHT indicates that the width of the image is 
+     * available.
+     */
+    public static final int HEIGHT = 2;
+
+    /** 
+     * The Constant PROPERTIES indicates that the properties of the image
+     * are available. 
+     */
+    public static final int PROPERTIES = 4;
+
+    /**
+     *  The Constant SOMEBITS indicates that more bits needed for 
+     *  drawing a scaled variation of the image pixels are available.
+     */
+    public static final int SOMEBITS = 8;
+
+    /** 
+     * The Constant FRAMEBITS indicates that complete frame of 
+     * a image which was previously drawn is now available
+     * for drawing again. 
+     */
+    public static final int FRAMEBITS = 16;
+
+    /** 
+     * The Constant ALLBITS indicates that an image which 
+     * was previously drawn is now complete and can be drawn again. 
+     */
+    public static final int ALLBITS = 32;
+
+    /** 
+     * The Constant ERROR indicates that error occured. 
+     */
+    public static final int ERROR = 64;
+
+    /** 
+     * The Constant ABORT indicates that the image producing is 
+     * aborted.
+     */
+    public static final int ABORT = 128;
+
+    /**
+     * This method is called when information about an Image
+     * interface becomes available. This method returns true 
+     * if further updates are needed, false if not.
+     * 
+     * @param img the image to be observed.
+     * @param infoflags the bitwise OR combination of information flags:
+     * ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, 
+     * WIDTH.
+     * @param x the X coordinate.
+     * @param y the Y coordinate.
+     * @param width the width.
+     * @param height the height.
+     * 
+     * @return true if further updates are needed, false if not.
+     */
+    public boolean imageUpdate(Image img, int infoflags, int x, int y,
+            int width, int height);
+
+}
+
diff --git a/awt/java/awt/image/ImageProducer.java b/awt/java/awt/image/ImageProducer.java
new file mode 100644
index 0000000..557ae08
--- /dev/null
+++ b/awt/java/awt/image/ImageProducer.java
@@ -0,0 +1,74 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * The ImageProducer provides an interface for objects which produce
+ * the image data. ImageProducer is used for reconstructing the 
+ * image. Each image contains an ImageProducer. 
+ */
+public interface ImageProducer {
+
+    /**
+     * Checks if the specified ImageConsumer is registered with this 
+     * ImageProvider or not.
+     * 
+     * @param ic the ImageConsumer to be checked.
+     * 
+     * @return true, if the specified ImageConsumer is registered with this 
+     * ImageProvider, false otherwise.
+     */
+    public boolean isConsumer(ImageConsumer ic);
+
+    /**
+     * Starts a reconstruction of the image data which will 
+     * be delivered to this consumer. This method addes the
+     * specified ImageConsumer before reconstructing the image.  
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void startProduction(ImageConsumer ic);
+
+    /**
+     * Requests the ImageProducer to resend the image data 
+     * in ImageConsumer.TOPDOWNLEFTRIGHT order.
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void requestTopDownLeftRightResend(ImageConsumer ic);
+
+    /**
+     * Deregisters the specified ImageConsumer.
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void removeConsumer(ImageConsumer ic);
+
+    /**
+     * Adds the specified ImageConsumer object to this ImageProducer.
+     * 
+     * @param ic the specified ImageConsumer.
+     */
+    public void addConsumer(ImageConsumer ic);
+
+}
+
diff --git a/awt/java/awt/image/ImagingOpException.java b/awt/java/awt/image/ImagingOpException.java
new file mode 100644
index 0000000..ebcaba4
--- /dev/null
+++ b/awt/java/awt/image/ImagingOpException.java
@@ -0,0 +1,44 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 5, 2005
+ */
+
+package java.awt.image;
+
+/**
+ * The ImagingOpException class provides error notification when 
+ * the BufferedImageOp or RasterOp filter methods can not perform
+ * the desired filter operation.
+ */
+public class ImagingOpException extends RuntimeException {
+    
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 8026288481846276658L;
+
+    /**
+     * Instantiates a new ImagingOpException with a detail message.
+     * 
+     * @param s the detail message.
+     */
+    public ImagingOpException(String s) {
+        super(s);
+    }
+}
diff --git a/awt/java/awt/image/IndexColorModel.java b/awt/java/awt/image/IndexColorModel.java
new file mode 100644
index 0000000..a7043f4
--- /dev/null
+++ b/awt/java/awt/image/IndexColorModel.java
@@ -0,0 +1,1020 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.math.BigInteger;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class IndexColorModel represents a color model in which the 
+ * color values of the pixels are read from a palette.
+ */
+public class IndexColorModel extends ColorModel {
+
+    /** The color map. */
+    private int colorMap[];        // Color Map  
+
+    /** The map size. */
+    private int mapSize;           // Color Map size
+
+    /** The transparent index. */
+    private int transparentIndex;  // Index of fully transparent pixel
+
+    /** The gray palette. */
+    private boolean grayPalette;   // Color Model has Color Map with Gray Pallete
+
+    /** The valid bits. */
+    private BigInteger validBits;  // Specify valid Color Map values
+
+    /** The Constant CACHESIZE. */
+    private static final int CACHESIZE = 20; // Cache size. Cache used for 
+                                             // improving performace of selection
+                                             // nearest color in Color Map
+
+    /** The cachetable. */
+    private final int cachetable[] = new int[CACHESIZE * 2]; // Cache table - used for 
+                               // storing RGB values and that appropriate indices 
+                               // in the Color Map 
+                    
+
+    /** The next insert idx. */
+    private int nextInsertIdx = 0;  // Next index for insertion into Cache table
+
+    /** The total inserted. */
+    private int totalInserted = 0;  // Number of inserted values into Cache table
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * @param validBits a list of which bits represent valid colormap 
+     * values, or null if all are valid
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, int cmap[], int start,
+            int transferType, BigInteger validBits) {
+
+        super(bits, IndexColorModel.createBits(true),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false,
+                Transparency.OPAQUE, validateTransferType(transferType));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        transparentIndex = -1;
+
+        if (validBits != null) {
+            for (int i = 0; i < mapSize; i++) {
+                if (!validBits.testBit(i)) {
+                    this.validBits = validBits;
+                }
+                break;
+            }
+        }
+
+        transparency = Transparency.OPAQUE;
+        int alphaMask = 0xff000000;
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++, start++) {
+            colorMap[i] = cmap[start];
+            alpha = cmap[start] & alphaMask;
+
+            if (alpha == alphaMask) {
+                continue;
+            }
+            if (alpha == 0) {
+                if (transparentIndex < 0) {
+                    transparentIndex = i;
+                }
+                if (transparency == Transparency.OPAQUE) {
+                    transparency = Transparency.BITMASK;
+                }
+            } else if (alpha != alphaMask &&
+                    transparency != Transparency.TRANSLUCENT) {
+                transparency = Transparency.TRANSLUCENT;
+            }
+
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param hasalpha whether this color model uses alpha
+     * @param trans the transparency supported, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, int cmap[], int start,
+            boolean hasalpha, int trans, int transferType) {
+
+        super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                (hasalpha || (trans >= 0)), false, Transparency.OPAQUE,
+                validateTransferType(transferType));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        if (trans >= 0 && trans < mapSize) {
+            transparentIndex = trans;
+            transparency = Transparency.BITMASK;
+        } else {
+            transparentIndex = -1;
+            transparency = Transparency.OPAQUE;
+        }
+
+        int alphaMask = 0xff000000;
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++, start++) {
+            if (transparentIndex == i) {
+                colorMap[i] = cmap[start] & 0x00ffffff;
+                continue;
+            }
+            if (hasalpha) {
+                alpha = cmap[start] & alphaMask;
+                colorMap[i] = cmap[start];
+
+                if (alpha == alphaMask) {
+                    continue;
+                }
+                if (alpha == 0) {
+                    if (trans < 0) {
+                        trans = i;
+                    }
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                    }
+                } else if (alpha != 0
+                        && transparency != Transparency.TRANSLUCENT) {
+                    transparency = Transparency.TRANSLUCENT;
+                }
+            } else {
+                colorMap[i] = alphaMask | cmap[start];
+            }
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map 
+     * from arrays of red, green, blue, and alpha values.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param r the array giving the red components of the entries in the color map
+     * @param g the array giving the green components of the entries in the color map
+     * @param b the array giving the blue components of the entries in the color map
+     * @param a the array giving the alpha components of the entries in the color map
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     * @throws ArrayIndexOutOfBoundsException if the size of one of the 
+     * component arrays is less than the size of the color map
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[],
+            byte a[]) {
+
+        super(bits, IndexColorModel.createBits(true),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false,
+                Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        createColorMap(size, r, g, b, a, -1);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map 
+     * from arrays of red, green, and blue values.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param r the array giving the red components of the entries in the color map
+     * @param g the array giving the green components of the entries in the color map
+     * @param b the array giving the blue components of the entries in the color map
+     * @param trans the transparency supported, @see java.awt.Transparency
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     * @throws ArrayIndexOutOfBoundsException if the size of one of the 
+     * component arrays is less than the size of the color map
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[],
+            int trans) {
+
+        super(bits, IndexColorModel.createBits((trans >= 0)),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), (trans >= 0), false,
+                Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        createColorMap(size, r, g, b, null, trans);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model by building the color map 
+     * from arrays of red, green, and blue values.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param r the array giving the red components of the entries in the color map
+     * @param g the array giving the green components of the entries in the color map
+     * @param b the array giving the blue components of the entries in the color map
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     * @throws ArrayIndexOutOfBoundsException if the size of one of the 
+     * component arrays is less than the size of the color map
+     */
+    public IndexColorModel(int bits, int size, byte r[], byte g[], byte b[]) {
+        super(bits, IndexColorModel.createBits(false),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB), false, false,
+                Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        createColorMap(size, r, g, b, null, -1);
+        checkPalette();
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param hasalpha whether this color model uses alpha
+     * @param trans the transparency supported, @see java.awt.Transparency
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, byte cmap[], int start,
+            boolean hasalpha, int trans) {
+
+        super(bits, IndexColorModel.createBits(hasalpha || (trans >= 0)),
+                ColorSpace.getInstance(ColorSpace.CS_sRGB),
+                (hasalpha || (trans >= 0)), false, Transparency.OPAQUE,
+                validateTransferType(ColorModel.getTransferType(bits)));
+
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        transparentIndex = -1;
+
+        transparency = Transparency.OPAQUE;
+        int alpha = 0xff000000;
+
+        for (int i = 0; i < mapSize; i++) {
+            colorMap[i] = (cmap[start++] & 0xff) << 16 |
+                   (cmap[start++] & 0xff) << 8 | (cmap[start++] & 0xff);
+            if (trans == i) {
+                if (transparency == Transparency.OPAQUE) {
+                    transparency = Transparency.BITMASK;
+                }
+                if(hasalpha) {
+                    start++;
+                }
+                continue;
+            }
+            if (hasalpha) {
+                alpha = cmap[start++] & 0xff;
+                if (alpha == 0) {
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                        if (trans < 0) {
+                            trans = i;
+                        }
+                    }
+                } else {
+                    if (alpha != 0xff &&
+                           transparency != Transparency.TRANSLUCENT) {
+                        transparency = Transparency.TRANSLUCENT;
+                    }
+                }
+                alpha <<= 24;
+            }
+            colorMap[i] |= alpha;
+        }
+
+        if (trans >= 0 && trans < mapSize) {
+            transparentIndex = trans;
+        }
+        checkPalette();
+
+    }
+
+    /**
+     * Instantiates a new index color model.
+     * 
+     * @param bits the array of component masks
+     * @param size the size of the color map
+     * @param cmap the array that gives the color mapping
+     * @param start the start index of the color mapping data within the cmap array
+     * @param hasalpha whether this color model uses alpha
+     * 
+     * @throws IllegalArgumentException if the size of the color map is
+     * less than one
+     */
+    public IndexColorModel(int bits, int size, byte cmap[], int start,
+            boolean hasalpha) {
+
+        this(bits, size, cmap, start, hasalpha, -1);
+    }
+
+    @Override
+    public Object getDataElements(int[] components, int offset, Object pixel) {
+        int rgb = (components[offset] << 16) | (components[offset + 1]) << 8 |
+               components[offset + 2];
+        if (hasAlpha) {
+            rgb |= components[offset + 3] << 24;
+        } else {
+            rgb |= 0xff000000;
+        }
+        return getDataElements(rgb, pixel);
+    }
+
+    @Override
+    public synchronized Object getDataElements(int rgb, Object pixel) {
+        int red = (rgb >> 16) & 0xff;
+        int green = (rgb >> 8) & 0xff;
+        int blue = rgb & 0xff;
+        int alpha = rgb >>> 24;
+        int pixIdx = 0;
+
+        for (int i = 0; i < totalInserted; i++) {
+            int idx = i * 2;
+            if (rgb == cachetable[idx]) {
+                return createDataObject(cachetable[idx + 1], pixel);
+            }
+        }
+
+        if (!hasAlpha && grayPalette) {
+            int grey = (red * 77 + green * 150 + blue * 29 + 128) >>> 8;
+            int minError = 255;
+            int error = 0;
+
+            for (int i = 0; i < mapSize; i++) {
+                error = Math.abs((colorMap[i] & 0xff) - grey);
+                if (error < minError) {
+                    pixIdx = i;
+                    if (error == 0) {
+                        break;
+                    }
+                    minError = error;
+                }
+            }
+        } else if (alpha == 0 && transparentIndex > -1) {
+            pixIdx = transparentIndex;
+        } else  {
+            int minAlphaError = 255;
+            int minError = 195075; // 255^2 + 255^2 + 255^2
+            int alphaError;
+            int error = 0;
+
+            for (int i = 0; i < mapSize; i++) {
+                int pix = colorMap[i];
+                if (rgb == pix) {
+                    pixIdx = i;
+                    break;
+                }
+                alphaError = Math.abs(alpha - (pix >>> 24));
+                if (alphaError <= minAlphaError) {
+                    minAlphaError = alphaError;
+
+                    int buf = ((pix >> 16) & 0xff) - red;
+                    error = buf * buf;
+
+                    if (error < minError) {
+                        buf = ((pix >> 8) & 0xff) - green;
+                        error += buf * buf;
+
+                        if (error < minError) {
+                            buf = (pix & 0xff) - blue;
+                            error += buf * buf;
+
+                            if (error < minError) {
+                                pixIdx = i;
+                                minError = error;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        cachetable[nextInsertIdx] = rgb;
+        cachetable[nextInsertIdx + 1] = pixIdx;
+
+        nextInsertIdx = (nextInsertIdx + 2) % (CACHESIZE * 2);
+        if (totalInserted < CACHESIZE) {
+            totalInserted++;
+        }
+
+        return createDataObject(pixIdx, pixel);
+    }
+
+    /**
+     * Converts an image from indexed to RGB format.
+     * 
+     * @param raster the raster containing the source image
+     * @param forceARGB whether to use the default RGB color model
+     * 
+     * @return the buffered image
+     * 
+     * @throws IllegalArgumentException if the raster is not compatible with 
+     * this color model
+     */
+    public BufferedImage convertToIntDiscrete(Raster raster,
+            boolean forceARGB) {
+
+        if (!isCompatibleRaster(raster)) {
+            // awt.265=The raster argument is not compatible with this IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.265")); //$NON-NLS-1$
+        }
+
+        ColorModel model;
+        if (forceARGB || transparency == Transparency.TRANSLUCENT) {
+            model = ColorModel.getRGBdefault();
+        } else if (transparency == Transparency.BITMASK) {
+            model = new DirectColorModel(25, 0x00ff0000, 0x0000ff00,
+                    0x000000ff, 0x01000000);
+        } else {
+            model = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff);
+        }
+
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        WritableRaster distRaster = model.createCompatibleWritableRaster(w, h);
+
+        int minX = raster.getMinX();
+        int minY = raster.getMinY();
+
+        Object obj = null;
+        int pixels[] = null;
+
+        for (int i = 0; i < h; i++, minY++) {
+            obj = raster.getDataElements(minX, minY, w, 1, obj);
+            if (obj instanceof byte[]) {
+                byte ba[] = (byte[]) obj;
+                if (pixels == null) {
+                    pixels = new int[ba.length];
+                }
+                for (int j = 0; j < ba.length; j++) {
+                    pixels[j] = colorMap[ba[j] & 0xff];
+                }
+            } else if (obj instanceof short[]) {
+                short sa[] = (short[]) obj;
+                if (pixels == null) {
+                    pixels = new int[sa.length];
+                }
+                for (int j = 0; j < sa.length; j++) {
+                    pixels[j] = colorMap[sa[j] & 0xffff];
+                }
+            }
+            if (obj instanceof int[]) {
+                int ia[] = (int[]) obj;
+                if (pixels == null) {
+                    pixels = new int[ia.length];
+                }
+                for (int j = 0; j < ia.length; j++) {
+                    pixels[j] = colorMap[ia[j]];
+                }
+            }
+
+            distRaster.setDataElements(0, i, w, 1, pixels);
+        }
+
+        return new BufferedImage(model, distRaster, false, null);
+    }
+
+    /**
+     * Gets the valid pixels.
+     * 
+     * @return the valid pixels
+     */
+    public BigInteger getValidPixels() {
+        return validBits;
+    }
+
+    @Override
+    public String toString() {
+        // The output format based on 1.5 release behaviour. 
+        // It could be reveled such way:
+        // BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_INDEXED);
+        // ColorModel cm = bi.getColorModel();
+        // System.out.println(cm.toString());
+        String str = "IndexColorModel: #pixel_bits = " + pixel_bits + //$NON-NLS-1$
+               " numComponents = " + numComponents + " color space = " + cs + //$NON-NLS-1$ //$NON-NLS-2$
+               " transparency = "; //$NON-NLS-1$
+
+        if (transparency == Transparency.OPAQUE) {
+            str = str + "Transparency.OPAQUE"; //$NON-NLS-1$
+        } else if (transparency == Transparency.BITMASK) {
+            str = str + "Transparency.BITMASK"; //$NON-NLS-1$
+        } else {
+            str = str + "Transparency.TRANSLUCENT"; //$NON-NLS-1$
+        }
+
+        str = str + " transIndex = " + transparentIndex + " has alpha = " + //$NON-NLS-1$ //$NON-NLS-2$
+               hasAlpha + " isAlphaPre = " + isAlphaPremultiplied; //$NON-NLS-1$
+
+        return str;
+    }
+
+    @Override
+    public int[] getComponents(Object pixel, int components[], int offset) {
+        int pixIdx = -1;
+        if (pixel instanceof byte[]) {
+            byte ba[] = (byte[]) pixel;
+            pixIdx = ba[0] & 0xff;
+        } else if (pixel instanceof short[]) {
+            short sa[] = (short[]) pixel;
+            pixIdx = sa[0] & 0xffff;
+        } else if (pixel instanceof int[]) {
+            int ia[] = (int[]) pixel;
+            pixIdx = ia[0];
+        } else {
+            // awt.219=This transferType is not supported by this color model
+            throw new UnsupportedOperationException(Messages.getString("awt.219")); //$NON-NLS-1$
+        }
+
+        return getComponents(pixIdx, components, offset);
+    }
+
+    @Override
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        WritableRaster raster;
+        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
+            raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w, h, 1,
+                    pixel_bits, null);
+        } else if (pixel_bits <= 8) {
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+                    1, null);
+        } else if (pixel_bits <= 16) {
+            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT, w,
+                    h, 1, null);
+        } else {
+            // awt.266=The number of bits in a pixel is greater than 16
+            throw new UnsupportedOperationException(Messages.getString("awt.266")); //$NON-NLS-1$
+        }
+
+        return raster;
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (sm == null) {
+            return false;
+        }
+
+        if (!(sm instanceof MultiPixelPackedSampleModel)
+                && !(sm instanceof ComponentSampleModel)) {
+            return false;
+        }
+
+        if (sm.getTransferType() != transferType) {
+            return false;
+        }
+        if (sm.getNumBands() != 1) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
+            return new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, w, h,
+                    pixel_bits);
+        }
+        int bandOffsets[] = new int[1];
+        bandOffsets[0] = 0;
+        return new ComponentSampleModel(transferType, w, h, 1, w,
+                bandOffsets);
+
+    }
+
+    @Override
+    public boolean isCompatibleRaster(Raster raster) {
+        int sampleSize = raster.getSampleModel().getSampleSize(0);
+        return (raster.getTransferType() == transferType &&
+               raster.getNumBands() == 1 && (1 << sampleSize) >= mapSize);
+    }
+
+    @Override
+    public int getDataElement(int components[], int offset) {
+        int rgb = (components[offset] << 16) | (components[offset + 1]) << 8
+                | components[offset + 2];
+        
+        if (hasAlpha) {
+            rgb |= components[offset + 3] << 24;
+        } else {
+            rgb |= 0xff000000;
+        }
+ 
+        int pixel;
+
+        switch (transferType) {
+        case DataBuffer.TYPE_BYTE:
+            byte ba[] = (byte[]) getDataElements(rgb, null);
+            pixel = ba[0] & 0xff;
+            break;
+        case DataBuffer.TYPE_USHORT:
+            short sa[] = (short[]) getDataElements(rgb, null);
+            pixel = sa[0] & 0xffff;
+            break;
+        default:
+            // awt.267=The transferType is invalid
+            throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Gets the color map.
+     * 
+     * @param rgb the destination array where the color map is written
+     */
+    public final void getRGBs(int rgb[]) {
+        System.arraycopy(colorMap, 0, rgb, 0, mapSize);
+    }
+
+    /**
+     * Gets the red component of the color map.
+     * 
+     * @param r the destination array
+     */
+    public final void getReds(byte r[]) {
+        for (int i = 0; i < mapSize; i++) {
+            r[i] = (byte) (colorMap[i] >> 16);
+        }
+    }
+
+    /**
+     * Gets the green component of the color map.
+     * 
+     * @param g the destination array
+     */
+    public final void getGreens(byte g[]) {
+        for (int i = 0; i < mapSize; i++) {
+            g[i] = (byte) (colorMap[i] >> 8);
+        }
+    }
+
+    /**
+     * Gets the blue component of the color map.
+     * 
+     * @param b the destination array
+     */
+    public final void getBlues(byte b[]) {
+        for (int i = 0; i < mapSize; i++) {
+            b[i] = (byte) colorMap[i];
+        }
+    }
+
+    /**
+     * Gets the alpha component of the color map.
+     * 
+     * @param a the destination array
+     */
+    public final void getAlphas(byte a[]) {
+        for (int i = 0; i < mapSize; i++) {
+            a[i] = (byte) (colorMap[i] >> 24);
+        }
+    }
+
+    @Override
+    public int[] getComponents(int pixel, int components[], int offset) {
+        if (components == null) {
+            components = new int[offset + numComponents];
+        }
+
+        components[offset + 0] = getRed(pixel);
+        components[offset + 1] = getGreen(pixel);
+        components[offset + 2] = getBlue(pixel);
+        if (hasAlpha && (components.length - offset) > 3) {
+            components[offset + 3] = getAlpha(pixel);
+        }
+
+        return components;
+    }
+
+    /**
+     * Checks if the specified pixel is valid for this color model.
+     * 
+     * @param pixel the pixel
+     * 
+     * @return true, if the pixel is valid
+     */
+    public boolean isValid(int pixel) {
+        if (validBits == null) {
+            return (pixel >= 0 && pixel < mapSize);
+        }
+        return (pixel < mapSize && validBits.testBit(pixel));
+    }
+
+    @Override
+    public final int getRed(int pixel) {
+        return (colorMap[pixel] >> 16) & 0xff;
+    }
+
+    @Override
+    public final int getRGB(int pixel) {
+        return colorMap[pixel];
+    }
+
+    @Override
+    public final int getGreen(int pixel) {
+        return (colorMap[pixel] >> 8) & 0xff;
+    }
+
+    @Override
+    public final int getBlue(int pixel) {
+        return colorMap[pixel] & 0xff;
+    }
+
+    @Override
+    public final int getAlpha(int pixel) {
+        return (colorMap[pixel] >> 24) & 0xff;
+    }
+
+    @Override
+    public int[] getComponentSize() {
+        return bits.clone();
+    }
+
+    /**
+     * Checks if this color model validates pixels.
+     * 
+     * @return true, if all pixels are valid, otherwise false
+     */
+    public boolean isValid() {
+        return (validBits == null);
+    }
+
+    @Override
+    public void finalize() {
+        // TODO: implement
+        return;
+    }
+
+    /**
+     * Gets the index that represents the transparent pixel.
+     * 
+     * @return the index that represents the transparent pixel
+     */
+    public final int getTransparentPixel() {
+        return transparentIndex;
+    }
+
+    @Override
+    public int getTransparency() {
+        return transparency;
+    }
+
+    /**
+     * Gets the size of the color map.
+     * 
+     * @return the map size
+     */
+    public final int getMapSize() {
+        return mapSize;
+    }
+
+    /**
+     * Creates the color map.
+     * 
+     * @param size the size
+     * @param r the r
+     * @param g the g
+     * @param b the b
+     * @param a the a
+     * @param trans the trans
+     */
+    private void createColorMap(int size, byte r[], byte g[], byte b[],
+            byte a[], int trans) {
+        if (size < 1) {
+            // awt.264=Size of the color map is less than 1
+            throw new IllegalArgumentException(Messages.getString("awt.264")); //$NON-NLS-1$
+        }
+
+        mapSize = size;
+        colorMap = new int[mapSize];
+        if (trans >= 0 && trans < mapSize) {
+            transparency = Transparency.BITMASK;
+            transparentIndex = trans;
+        } else {
+            transparency = Transparency.OPAQUE;
+            transparentIndex = -1;
+        }
+        int alpha = 0;
+
+        for (int i = 0; i < mapSize; i++) {
+            colorMap[i] = ((r[i] & 0xff) << 16) | ((g[i] & 0xff) << 8) |
+                   (b[i] & 0xff);
+
+            if (trans == i) {
+                continue;
+            }
+
+            if (a == null) {
+                colorMap[i] |= 0xff000000;
+            } else {
+                alpha = a[i] & 0xff;
+                if (alpha == 0xff) {
+                    colorMap[i] |= 0xff000000;
+                } else if (alpha == 0) {
+                    if (transparency == Transparency.OPAQUE) {
+                        transparency = Transparency.BITMASK;
+                    }
+                    if (transparentIndex < 0) {
+                        transparentIndex = i;
+                    }
+                } else {
+                    colorMap[i] |= (a[i] & 0xff) << 24;
+                    if (transparency != Transparency.TRANSLUCENT) {
+                        transparency = Transparency.TRANSLUCENT;
+                    }
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * This method checking, if Color Map has Gray Palette.
+     */
+    private void checkPalette() {
+        grayPalette = false;
+        if (transparency > Transparency.OPAQUE) {
+            return;
+        }
+        int rgb = 0;
+
+        for (int i = 0; i < mapSize; i++) {
+            rgb = colorMap[i];
+            if (((rgb >> 16) & 0xff) != ((rgb >> 8) & 0xff) ||
+                   ((rgb >> 8) & 0xff) != (rgb & 0xff)) {
+                return;
+            }
+        }
+        grayPalette = true;
+    }
+
+    /**
+     * Construction an array pixel representation.
+     * 
+     * @param colorMapIdx - index into Color Map
+     * @param pixel - pixel
+     * 
+     * @return - an array pixel representation
+     */
+    private Object createDataObject(int colorMapIdx, Object pixel) {
+        if (pixel == null) {
+            switch (transferType) {
+            case DataBuffer.TYPE_BYTE:
+                byte[] ba = new byte[1];
+                ba[0] = (byte) colorMapIdx;
+                pixel = ba;
+                break;
+            case DataBuffer.TYPE_USHORT:
+                short[] sa = new short[1];
+                sa[0] = (short) colorMapIdx;
+                pixel = sa;
+                break;
+            default:
+                // awt.267=The transferType is invalid
+                throw new UnsupportedOperationException(Messages.getString("awt.267")); //$NON-NLS-1$
+            }
+        } else if (pixel instanceof byte[]
+                && transferType == DataBuffer.TYPE_BYTE) {
+            byte ba[] = (byte[]) pixel;
+            ba[0] = (byte) colorMapIdx;
+            pixel = ba;
+        } else if (pixel instanceof short[]&&
+                transferType == DataBuffer.TYPE_USHORT) {
+            short[] sa = (short[]) pixel;
+            sa[0] = (short) colorMapIdx;
+            pixel = sa;
+        } else if (pixel instanceof int[]) {
+            int ia[] = (int[]) pixel;
+            ia[0] = colorMapIdx;
+            pixel = ia;
+        } else {
+            // awt.268=The pixel is not a primitive array of type transferType
+            throw new ClassCastException(Messages.getString("awt.268")); //$NON-NLS-1$
+        }
+        return pixel;
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param hasAlpha the has alpha
+     * 
+     * @return the int[]
+     */
+    private static int[] createBits(boolean hasAlpha) {
+
+        int numChannels;
+        if (hasAlpha) {
+            numChannels = 4;
+        } else {
+            numChannels = 3;
+        }
+
+        int bits[] = new int[numChannels];
+        for (int i = 0; i < numChannels; i++) {
+            bits[i] = 8;
+        }
+
+        return bits;
+
+    }
+
+    /**
+     * Validate transfer type.
+     * 
+     * @param transferType the transfer type
+     * 
+     * @return the int
+     */
+    private static int validateTransferType(int transferType) {
+        if (transferType != DataBuffer.TYPE_BYTE &&
+               transferType != DataBuffer.TYPE_USHORT) {
+            // awt.269=The transferType is not one of DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT
+            throw new IllegalArgumentException(Messages.getString("awt.269")); //$NON-NLS-1$
+        }
+        return transferType;
+    }
+
+    /**
+     * Checks if is gray pallete.
+     * 
+     * @return true, if is gray pallete
+     */
+    boolean isGrayPallete(){
+        return grayPalette;
+    }
+
+}
+
+
diff --git a/awt/java/awt/image/Kernel.java b/awt/java/awt/image/Kernel.java
new file mode 100644
index 0000000..c6f00e2
--- /dev/null
+++ b/awt/java/awt/image/Kernel.java
@@ -0,0 +1,138 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Sep 28, 2005
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Kernel class provides a matrix. This matrix is stored as a float array
+ * which describes how a specified pixel affects the value calculated for 
+ * the pixel's position in the output image of a filtering operation. 
+ * The X, Y origins indicate the kernel matrix element which corresponds to 
+ * the pixel position for which an output value is being calculated.
+ */
+public class Kernel implements Cloneable {
+    
+    /** The x origin. */
+    private final int xOrigin;
+    
+    /** The y origin. */
+    private final int yOrigin;
+    
+    /** The width. */
+    private int width;
+    
+    /** The height. */
+    private int height;
+    
+    /** The data. */
+    float data[];
+
+    /**
+     * Instantiates a new Kernel with the specified float array.
+     * The width*height elements of the data array are copied. 
+     * 
+     * @param width the width of the Kernel.
+     * @param height the height of the Kernel.
+     * @param data the data of Kernel.
+     */
+    public Kernel(int width, int height, float[] data) {
+        int dataLength = width*height;
+        if (data.length < dataLength) {
+            // awt.22B=Length of data should not be less than width*height
+            throw new IllegalArgumentException(Messages.getString("awt.22B")); //$NON-NLS-1$
+        }
+
+        this.width = width;
+        this.height = height;
+
+        this.data = new float[dataLength];
+        System.arraycopy(data, 0, this.data, 0, dataLength);
+
+        xOrigin = (width-1)/2;
+        yOrigin = (height-1)/2;
+    }
+
+    /**
+     * Gets the width of this Kernel.
+     * 
+     * @return the width of this Kernel.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the height of this Kernel.
+     * 
+     * @return the height of this Kernel.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the float data array of this Kernel.
+     * 
+     * @param data the float array where the resulted data will be stored.
+     * 
+     * @return the float data array of this Kernel.
+     */
+    public final float[] getKernelData(float[] data) {
+        if (data == null) {
+            data = new float[this.data.length];
+        }
+        System.arraycopy(this.data, 0, data, 0, this.data.length);
+
+        return data;
+    }
+
+    /**
+     * Gets the X origin of this Kernel.
+     * 
+     * @return the X origin of this Kernel.
+     */
+    public final int getXOrigin() {
+        return xOrigin;
+    }
+
+    /**
+     * Gets the Y origin of this Kernel.
+     * 
+     * @return the Y origin of this Kernel.
+     */
+    public final int getYOrigin() {
+        return yOrigin;
+    }
+
+    /**
+     * Returns a copy of this Kernel object.
+     * 
+     * @return the copy of this Kernel object.
+     */
+    @Override
+    public Object clone() {
+        return new Kernel(width, height, data);
+    }
+}
diff --git a/awt/java/awt/image/LookupOp.java b/awt/java/awt/image/LookupOp.java
new file mode 100644
index 0000000..f9bd2c7
--- /dev/null
+++ b/awt/java/awt/image/LookupOp.java
@@ -0,0 +1,647 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The LookupOp class perfoms a lookup operation which transforms a 
+ * source image by filtering each band using a table of data. 
+ * The table may contain a single array or it may contain a 
+ * different data array for each band of the image.
+ */
+public class LookupOp implements BufferedImageOp, RasterOp {
+    
+    /** The lut. */
+    private final LookupTable lut;
+    
+    /** The hints. */
+    private RenderingHints hints;
+    
+    // TODO remove when this field is used
+    /** The can use ipp. */
+    @SuppressWarnings("unused")
+    private final boolean canUseIpp;
+
+    // We don't create levels/values when it is possible to reuse old
+    /** The cached levels. */
+    private int cachedLevels[];
+    
+    /** The cached values. */
+    private int cachedValues[];
+    // Number of channels for which cache is valid.
+    // If negative number of channels is same as positive but skipAlpha was specified
+    /** The valid for channels. */
+    private int validForChannels;
+
+    /** The level initializer. */
+    static int levelInitializer[] = new int[0x10000];
+
+    static {
+        // TODO
+        // System.loadLibrary("imageops");
+
+        for (int i=1; i<=0x10000; i++) {
+            levelInitializer[i-1] = i;
+        }
+    }
+
+    /**
+     * Instantiates a new LookupOp object from the specified 
+     * LookupTable object and a RenderingHints object.
+     * 
+     * @param lookup the specified LookupTable object. 
+     * @param hints the RenderingHints object or null.
+     */
+    public LookupOp(LookupTable lookup, RenderingHints hints) {
+        if (lookup == null){
+            throw new NullPointerException(Messages.getString("awt.01", "lookup")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        lut = lookup;
+        this.hints = hints;
+        canUseIpp = lut instanceof ByteLookupTable || lut instanceof ShortLookupTable;
+    }
+
+    /**
+     * Gets the LookupTable of the specified Object.
+     * 
+     * @return the LookupTable of the specified Object.
+     */
+    public final LookupTable getTable() {
+        return lut;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+
+            // Sync transfer type with LUT for component color model
+            if (dstCM instanceof ComponentColorModel) {
+                int transferType = dstCM.getTransferType();
+                if (lut instanceof ByteLookupTable) {
+                    transferType = DataBuffer.TYPE_BYTE;
+                } else if (lut instanceof ShortLookupTable) {
+                    transferType = DataBuffer.TYPE_SHORT;
+                }
+
+                dstCM = new ComponentColorModel(
+                        dstCM.cs,
+                        dstCM.hasAlpha(),
+                        dstCM.isAlphaPremultiplied,
+                        dstCM.transparency,
+                        transferType
+                );
+            }
+        }
+
+        WritableRaster r =
+                dstCM.isCompatibleSampleModel(src.getSampleModel()) ?
+                src.getRaster().createCompatibleWritableRaster(src.getWidth(), src.getHeight()) :
+                dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(
+                dstCM,
+                r,
+                dstCM.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else {
+            if (src.getNumBands() != dst.getNumBands()) {
+                throw new IllegalArgumentException(Messages.getString("awt.237")); //$NON-NLS-1$            }
+            }
+            if (src.getWidth() != dst.getWidth()){
+                throw new IllegalArgumentException(Messages.getString("awt.28F")); //$NON-NLS-1$            }
+            }
+            if (src.getHeight() != dst.getHeight()){
+                throw new IllegalArgumentException(Messages.getString("awt.290")); //$NON-NLS-1$            }
+            }
+        }
+
+        if (lut.getNumComponents() != 1 && lut.getNumComponents() != src.getNumBands()) {
+            // awt.238=The number of arrays in the LookupTable does not meet the restrictions
+            throw new IllegalArgumentException(Messages.getString("awt.238")); //$NON-NLS-1$
+        }
+
+        // TODO
+        // if (!canUseIpp || ippFilter(src, dst, BufferedImage.TYPE_CUSTOM, false) != 0)
+            if (slowFilter(src, dst, false) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        return dst;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        ColorModel srcCM = src.getColorModel();
+
+        if (srcCM instanceof IndexColorModel) {
+            // awt.220=Source should not have IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.220")); //$NON-NLS-1$
+        }
+
+        // Check if the number of scaling factors matches the number of bands
+        int nComponents = srcCM.getNumComponents();
+        int nLUTComponents = lut.getNumComponents();
+        boolean skipAlpha;
+        if (srcCM.hasAlpha()) {
+            if (nLUTComponents == 1 || nLUTComponents == nComponents-1) {
+                skipAlpha = true;
+            } else if (nLUTComponents == nComponents) {
+                skipAlpha = false;
+            } else {
+                // awt.229=Number of components in the LUT does not match the number of bands
+                throw new IllegalArgumentException(Messages.getString("awt.229")); //$NON-NLS-1$
+            }
+        } else if (nLUTComponents == 1 || nLUTComponents == nComponents) {
+            skipAlpha = false;
+        } else {
+            // awt.229=Number of components in the LUT does not match the number of bands
+            throw new IllegalArgumentException(Messages.getString("awt.229")); //$NON-NLS-1$
+        }
+
+        BufferedImage finalDst = null;
+        if (dst == null) {
+            finalDst = dst;
+            dst = createCompatibleDestImage(src, null);
+        } else {
+            if (src.getWidth() != dst.getWidth()){
+                throw new IllegalArgumentException(Messages.getString("awt.291")); //$NON-NLS-1$
+            }
+
+            if (src.getHeight() != dst.getHeight()){
+                throw new IllegalArgumentException(Messages.getString("awt.292")); //$NON-NLS-1$
+            }
+
+            if (!srcCM.equals(dst.getColorModel())) {
+                // Treat BufferedImage.TYPE_INT_RGB and
+                // BufferedImage.TYPE_INT_ARGB as same
+                if (!((src.getType() == BufferedImage.TYPE_INT_RGB || src
+                        .getType() == BufferedImage.TYPE_INT_ARGB) && (dst
+                        .getType() == BufferedImage.TYPE_INT_RGB || dst
+                        .getType() == BufferedImage.TYPE_INT_ARGB))) {
+                    finalDst = dst;
+                    dst = createCompatibleDestImage(src, null);
+                }
+            }
+        }
+
+        // TODO
+        //if (!canUseIpp || ippFilter(src.getRaster(), dst.getRaster(), src.getType(), skipAlpha) != 0)
+            if (slowFilter(src.getRaster(), dst.getRaster(), skipAlpha) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    private final int slowFilter(Raster src, WritableRaster dst, boolean skipAlpha) {
+        int minSrcX = src.getMinX();
+        int minDstX = dst.getMinX();
+        int minSrcY = src.getMinY();
+        int minDstY = dst.getMinY();
+
+        int skippingChannels = skipAlpha ? 1 : 0;
+        int numBands2Process = src.getNumBands() - skippingChannels;
+
+        int numBands = src.getNumBands();
+        int srcHeight = src.getHeight();
+        int srcWidth = src.getWidth();
+
+        int[] pixels = null;
+        int offset = lut.getOffset();
+
+        if (lut instanceof ByteLookupTable){
+            byte[][] byteData = ((ByteLookupTable)lut).getTable();
+            pixels = src.getPixels(minSrcX, minSrcY, srcWidth, srcHeight, pixels);
+
+            if (lut.getNumComponents() != 1){
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = byteData[b][pixels[i+b]-offset] & 0xFF;
+                    }
+                }
+            } else {
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = byteData[0][pixels[i+b]-offset] & 0xFF;
+                    }
+                }
+            }
+
+            dst.setPixels(minDstX, minDstY, srcWidth, srcHeight, pixels);
+        } else if (lut instanceof ShortLookupTable){
+            short[][] shortData  = ((ShortLookupTable)lut).getTable();
+            pixels = src.getPixels(minSrcX, minSrcY, srcWidth, srcHeight, pixels);
+
+            if (lut.getNumComponents() != 1){
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = shortData[b][pixels[i+b]-offset] & 0xFFFF;
+                    }
+                }
+            } else {
+                for (int i=0; i < pixels.length; i+= numBands){
+                    for (int b = 0; b < numBands2Process; b++){
+                        pixels[i+b] = shortData[0][pixels[i+b]-offset] & 0xFFFF;
+                    }
+                }
+            }
+
+            dst.setPixels(minDstX, minDstY, srcWidth, srcHeight, pixels);
+        } else {
+            int pixel[] = new int[src.getNumBands()];
+            int maxY = minSrcY + srcHeight;
+            int maxX = minSrcX + srcWidth;
+            for (int srcY=minSrcY, dstY = minDstY; srcY < maxY; srcY++, dstY++){
+                for (int srcX=minSrcX, dstX = minDstX; srcX < maxX; srcX++, dstX++){
+                    src.getPixel(srcX, srcY, pixel);
+                    lut.lookupPixel(pixel, pixel);
+                    dst.setPixel(dstX, dstY, pixel);
+                }
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Creates the byte levels.
+     * 
+     * @param channels the channels
+     * @param skipAlpha the skip alpha
+     * @param levels the levels
+     * @param values the values
+     * @param channelsOrder the channels order
+     */
+    private final void createByteLevels(
+            int channels, boolean skipAlpha,
+            int levels[], int values[], int channelsOrder[]
+    ) {
+        byte data[][] = ((ByteLookupTable)lut).getTable();
+        int nLevels = data[0].length;
+        int offset = lut.getOffset();
+
+        // Use one data array for all channels or use several data arrays
+        int dataIncrement = data.length > 1 ? 1 : 0;
+
+        for (int ch = 0, dataIdx = 0; ch<channels; dataIdx+=dataIncrement, ch++) {
+            int channelOffset = channelsOrder == null ? ch : channelsOrder[ch];
+            int channelBase = nLevels * channelOffset;
+
+            // Skip last channel if needed, zero values are OK -
+            // no changes to the channel information will be done in IPP
+            if ((channelOffset == channels-1 && skipAlpha) || (dataIdx >= data.length)) {
+                continue;
+            }
+
+            System.arraycopy(levelInitializer, offset, levels, channelBase, nLevels);
+            for (int from=0, to=channelBase; from<nLevels; from++, to++) {
+                values[to] = data[dataIdx][from] & 0xFF;
+            }
+        }
+    }
+
+    /**
+     * Creates the short levels.
+     * 
+     * @param channels the channels
+     * @param skipAlpha the skip alpha
+     * @param levels the levels
+     * @param values the values
+     * @param channelsOrder the channels order
+     */
+    private final void createShortLevels(
+            int channels, boolean skipAlpha,
+            int levels[], int values[], int channelsOrder[]
+    ) {
+        short data[][] = ((ShortLookupTable)lut).getTable();
+        int nLevels = data[0].length;
+        int offset = lut.getOffset();
+
+        // Use one data array for all channels or use several data arrays
+        int dataIncrement = data.length > 1 ? 1 : 0;
+
+        for (int ch = 0, dataIdx = 0; ch<channels; dataIdx+=dataIncrement, ch++) {
+            int channelOffset = channelsOrder == null ? ch : channelsOrder[ch];
+
+            // Skip last channel if needed, zero values are OK -
+            // no changes to the channel information will be done in IPP
+            if ((channelOffset == channels-1 && skipAlpha) || (dataIdx >= data.length)) {
+                continue;
+            }
+
+            int channelBase = nLevels * channelOffset;
+            System.arraycopy(levelInitializer, offset, levels, channelBase, nLevels);
+            for (int from=0, to=channelBase; from<nLevels; from++, to++) {
+                values[to] = data[dataIdx][from] & 0xFFFF;
+            }
+        }
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private final int ippFilter(
+            Raster src, WritableRaster dst,
+            int imageType, boolean skipAlpha
+    ) {
+        int res;
+
+        int srcStride, dstStride;
+        int channels;
+        int offsets[] = null;
+        int channelsOrder[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_INT_RGB: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                channelsOrder = new int[] {2, 1, 0, 3};
+                break;
+            }
+
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                channelsOrder = new int[] {2, 1, 0};
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY:
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst, skipAlpha);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Have IPP functions for 1, 3 and 4 channels
+                    channels = srcSM.getNumBands();
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride();
+
+                    channelsOrder = ((ComponentSampleModel) srcSM).getBandOffsets();
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 =
+                            (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 =
+                            (SinglePixelPackedSampleModel) dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                     // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (
+                            sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                            sppsm2.getDataType() != DataBuffer.TYPE_INT ||
+                            !(channels == 3 || channels == 4)
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst, skipAlpha);
+                        }
+                    }
+
+                    channelsOrder = new int[channels];
+                    int bitOffsets[] = sppsm1.getBitOffsets();
+                    for (int i=0; i<channels; i++) {
+                        channelsOrder[i] = bitOffsets[i] / 8;
+                    }
+
+                    if (channels == 3) { // Don't skip channel now, could be optimized
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst, skipAlpha);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        int levels[] = null, values[] = null;
+        int channelMultiplier = skipAlpha ? -1 : 1;
+        if (channelMultiplier*channels == validForChannels) { // use existing levels/values
+            levels = cachedLevels;
+            values = cachedValues;
+        } else { // create new levels/values
+            if (lut instanceof ByteLookupTable) {
+                byte data[][] = ((ByteLookupTable)lut).getTable();
+                levels = new int[channels*data[0].length];
+                values = new int[channels*data[0].length];
+                createByteLevels(channels, skipAlpha, levels, values, channelsOrder);
+            } else if (lut instanceof ShortLookupTable) {
+                short data[][] = ((ShortLookupTable)lut).getTable();
+                levels = new int[channels*data[0].length];
+                values = new int[channels*data[0].length];
+                createShortLevels(channels, skipAlpha, levels, values, channelsOrder);
+            }
+
+            // cache levels/values
+            validForChannels = channelMultiplier*channels;
+            cachedLevels = levels;
+            cachedValues = values;
+        }
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        res = ippLUT(
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            levels, values,
+            channels, offsets,
+            false
+        );
+
+        return res;
+    }
+
+    /**
+     * Ipp lut.
+     * 
+     * @param src the src
+     * @param srcWidth the src width
+     * @param srcHeight the src height
+     * @param srcStride the src stride
+     * @param dst the dst
+     * @param dstWidth the dst width
+     * @param dstHeight the dst height
+     * @param dstStride the dst stride
+     * @param levels the levels
+     * @param values the values
+     * @param channels the channels
+     * @param offsets the offsets
+     * @param linear the linear
+     * 
+     * @return the int
+     */
+    final static native int ippLUT(
+            Object src, int srcWidth, int srcHeight, int srcStride,
+            Object dst, int dstWidth, int dstHeight, int dstStride,
+            int levels[], int values[],
+            int channels, int offsets[],
+            boolean linear
+    );
+}
diff --git a/awt/java/awt/image/LookupTable.java b/awt/java/awt/image/LookupTable.java
new file mode 100644
index 0000000..d15f23c
--- /dev/null
+++ b/awt/java/awt/image/LookupTable.java
@@ -0,0 +1,93 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This abstract LookupTable class represents lookup table which
+ * is defined with the number of components and offset value.
+ * ByteLookupTable and ShortLookupTable classes are subclasses of
+ * LookupTable which contains byte and short data tables as
+ * an input arrays for bands or components of image.
+ */
+public abstract class LookupTable {
+    
+    /** The offset. */
+    private int offset;
+    
+    /** The num components. */
+    private int numComponents;
+
+    /**
+     * Instantiates a new LookupTable with the specified offset value
+     * and number of components.
+     * 
+     * @param offset the offset value.
+     * @param numComponents the number of components.
+     */
+    protected LookupTable(int offset, int numComponents) {
+        if (offset < 0) {
+            // awt.232=Offset should be not less than zero
+            throw new IllegalArgumentException(Messages.getString("awt.232")); //$NON-NLS-1$
+        }
+        if (numComponents < 1) {
+            // awt.233=Number of components should be positive
+            throw new IllegalArgumentException(Messages.getString("awt.233")); //$NON-NLS-1$
+        }
+
+        this.offset = offset;
+        this.numComponents = numComponents;
+    }
+
+    /**
+     * Gets the offset value of this Lookup table.
+     * 
+     * @return the offset value of this Lookup table.
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Gets the number of components of this Lookup table.
+     * 
+     * @return the number components of this Lookup table.
+     */
+    public int getNumComponents() {
+        return numComponents;
+    }
+
+    /**
+     * Returns a int array which contains samples of the specified
+     * pixel which is translated with the lookup table of this 
+     * LookupTable. The resulted array is stored to the dst array.
+     * 
+     * @param src the source array.
+     * @param dst the destination array where the result can be stored.
+     * 
+     * @return the int array of translated samples of a pixel.
+     */
+    public abstract int[] lookupPixel(int[] src, int[] dst);
+}
diff --git a/awt/java/awt/image/MemoryImageSource.java b/awt/java/awt/image/MemoryImageSource.java
new file mode 100644
index 0000000..983f19e
--- /dev/null
+++ b/awt/java/awt/image/MemoryImageSource.java
@@ -0,0 +1,512 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The MemoryImageSource class is used to produces pixels of an image from
+ * an array. This class can manage a memory image which 
+ * contains an animation or custom rendering.
+ */
+public class MemoryImageSource implements ImageProducer {
+
+    /** The width. */
+    int width;
+    
+    /** The height. */
+    int height;
+    
+    /** The cm. */
+    ColorModel cm;
+    
+    /** The b data. */
+    byte bData[];
+    
+    /** The i data. */
+    int iData[];
+    
+    /** The offset. */
+    int offset;
+    
+    /** The scanline. */
+    int scanline;
+    
+    /** The properties. */
+    Hashtable<?, ?> properties;
+    
+    /** The consumers. */
+    Vector<ImageConsumer> consumers;
+    
+    /** The animated. */
+    boolean animated;
+    
+    /** The fullbuffers. */
+    boolean fullbuffers;
+    
+    /** The data type. */
+    int dataType;
+
+    /** The Constant DATA_TYPE_BYTE. */
+    static final int DATA_TYPE_BYTE = 0;
+    
+    /** The Constant DATA_TYPE_INT. */
+    static final int DATA_TYPE_INT = 1;
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     * @param props the set of properties to be used for image
+     * processing.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, int pix[],
+            int off, int scan, Hashtable<?, ?> props) {
+        init(w, h, cm, pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     * @param props the set of properties to be used for image
+     * processing.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, byte pix[],
+            int off, int scan, Hashtable<?, ?> props) {
+        init(w, h, cm, pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters and default RGB ColorModel.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     * @param props the set of properties to be used for image
+     * processing.
+     */
+    public MemoryImageSource(int w, int h, int pix[], int off, int scan,
+            Hashtable<?, ?> props) {
+        init(w, h, ColorModel.getRGBdefault(), pix, off, scan, props);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, int pix[],
+            int off, int scan) {
+        init(w, h, cm, pix, off, scan, null);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param cm the specified ColorModel.
+     * @param pix the pixel array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     */
+    public MemoryImageSource(int w, int h, ColorModel cm, byte pix[],
+            int off, int scan) {
+        init(w, h, cm, pix, off, scan, null);
+    }
+
+    /**
+     * Instantiates a new MemoryImageSource with the specified
+     * parameters and default RGB ColorModel.
+     * 
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param pix the pixels array.
+     * @param off the offset in the pixel array.
+     * @param scan the distance from one pixel's row to the next 
+     * in the pixel array.
+     */
+    public MemoryImageSource(int w, int h, int pix[], int off, int scan) {
+        init(w, h, ColorModel.getRGBdefault(), pix, off, scan, null);
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        return consumers.contains(ic);
+    }
+
+    public void startProduction(ImageConsumer ic) {
+        if(!isConsumer(ic) && ic != null) {
+            consumers.addElement(ic);
+        }
+        try{
+            setHeader(ic);
+            setPixels(ic, 0, 0, width, height);
+            if(animated){
+                ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
+            }else{
+                ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
+                if(isConsumer(ic)) {
+                    removeConsumer(ic);
+                }
+            }
+        }catch(Exception e){
+            if(isConsumer(ic)) {
+                ic.imageComplete(ImageConsumer.IMAGEERROR);
+            }
+            if(isConsumer(ic)) {
+                removeConsumer(ic);
+            }
+        }
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        consumers.removeElement(ic);
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if(ic == null || consumers.contains(ic)) {
+            return;
+        }
+        consumers.addElement(ic);
+    }
+
+    /**
+     * Replaces the pixel data with a new pixel array for holding 
+     * the pixels for this image. If an animation 
+     * flag is set to true value by the setAnimated() method, 
+     * the new pixels will be immediately delivered to the ImageConsumers. 
+     * 
+     * @param newpix the new pixel array.
+     * @param newmodel the new ColorModel.
+     * @param offset the offset in the array.
+     * @param scansize the distance from one row of pixels to the next row
+     * in the pixel array
+     */
+    public synchronized void newPixels(int newpix[], ColorModel newmodel,
+            int offset, int scansize) {
+        this.dataType = DATA_TYPE_INT;
+        this.iData = newpix;
+        this.cm = newmodel;
+        this.offset = offset;
+        this.scanline = scansize;
+        newPixels();
+    }
+
+    /**
+     * Replaces the pixel data with a new pixel array for holding 
+     * the pixels for this image. If an animation 
+     * flag is set to true value by the setAnimated() method, 
+     * the new pixels will be immediately delivered to the ImageConsumers. 
+     * 
+     * @param newpix the new pixel array.
+     * @param newmodel the new ColorModel.
+     * @param offset the offset in the array.
+     * @param scansize the distance from one row of pixels to the next row
+     * in the pixel array
+     */
+    public synchronized void newPixels(byte newpix[], ColorModel newmodel,
+            int offset, int scansize) {
+        this.dataType = DATA_TYPE_BYTE;
+        this.bData = newpix;
+        this.cm = newmodel;
+        this.offset = offset;
+        this.scanline = scansize;
+        newPixels();
+    }
+
+    /**
+     * Sets the full buffer updates flag to true. If this is an 
+     * animated image, the image consumers hints are updated
+     * accordingly.
+     * 
+     * @param fullbuffers the true if the pixel buffer should be sent always.
+     */
+    public synchronized void setFullBufferUpdates(boolean fullbuffers) {
+        if(this.fullbuffers == fullbuffers) {
+            return;
+        }
+        this.fullbuffers = fullbuffers;
+        if(animated){
+            Object consAr[] = consumers.toArray();
+            for (Object element : consAr) {
+                ImageConsumer con = (ImageConsumer)element;
+                try{
+                    if(fullbuffers){
+                        con.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
+                                ImageConsumer.COMPLETESCANLINES);
+                    }else{
+                        con.setHints(ImageConsumer.RANDOMPIXELORDER);
+                    }
+                }catch(Exception e){
+                    if(isConsumer(con)) {
+                        con.imageComplete(ImageConsumer.IMAGEERROR);
+                    }
+                    if(isConsumer(con)) {
+                        removeConsumer(con);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the flag that tells whether this memory image has more 
+     * than one frame (for animation): true for multiple frames,
+     * false if this class represents a single frame image.
+     *  
+     * @param animated whether this image represents an animation.
+     */
+    public synchronized void setAnimated(boolean animated) {
+        if(this.animated == animated) {
+            return;
+        }
+        Object consAr[] = consumers.toArray();
+        for (Object element : consAr) {
+            ImageConsumer con = (ImageConsumer)element;
+            try{
+                con.imageComplete(ImageConsumer.STATICIMAGEDONE);
+            }catch(Exception e){
+                if(isConsumer(con)) {
+                    con.imageComplete(ImageConsumer.IMAGEERROR);
+                }
+            }
+            if(isConsumer(con)){
+                removeConsumer(con);
+            }
+        }
+        this.animated = animated;
+    }
+
+    /**
+     * Sends the specified rectangular area of the buffer to 
+     * ImageConsumers and notifies them that an animation frame 
+     * is completed only if framenotify parameter is true.
+     * That works only if the animated flag has been set to true 
+     * by the setAnimated() method. If the full buffer update flag 
+     * has been set to true by the setFullBufferUpdates() method, 
+     * then the entire buffer will always be sent ignoring parameters.
+     * 
+     * @param x the X coordinate of the rectangular area.
+     * @param y the Y coordinate of rthe ectangular area.
+     * @param w the width of the rectangular area.
+     * @param h the height of the rectangular area. 
+     * @param framenotify true if a SINGLEFRAMEDONE notification
+     * should be sent to the registered consumers, false otherwise. 
+     */
+    public synchronized void newPixels(int x, int y, int w, int h,
+            boolean framenotify) {
+        if(animated){
+            if(fullbuffers){
+                x = 0;
+                y = 0;
+                w = width;
+                h = height;
+            }else{
+                if(x < 0){
+                    w += x;
+                    x = 0;
+                }
+                if(w > width) {
+                    w = width - x;
+                }
+                if(y < 0){
+                    h += y;
+                    y = 0;
+                }
+            }
+            if(h > height) {
+                h = height - y;
+            }
+            Object consAr[] = consumers.toArray();
+            for (Object element : consAr) {
+                ImageConsumer con = (ImageConsumer)element;
+                try{
+                    if(w > 0 && h > 0) {
+                        setPixels(con, x, y, w, h);
+                    }
+                    if(framenotify) {
+                        con.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
+                    }
+                }catch(Exception ex){
+                    if(isConsumer(con)) {
+                        con.imageComplete(ImageConsumer.IMAGEERROR);
+                    }
+                    if(isConsumer(con)) {
+                        removeConsumer(con);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sends the specified rectangular area of the buffer to 
+     * the ImageConsumers and notifies them that an animation frame 
+     * is completed if the animated flag has been set to true 
+     * by the setAnimated() method. If the full buffer update flag 
+     * has been set to true by the setFullBufferUpdates() method, 
+     * then the entire buffer will always be sent ignoring parameters.
+     * 
+     * @param x the X coordinate of the rectangular area.
+     * @param y the Y coordinate of the rectangular area.
+     * @param w the width of the rectangular area.
+     * @param h the height of the rectangular area. 
+     */
+    public synchronized void newPixels(int x, int y, int w, int h) {
+        newPixels(x, y, w, h, true);
+    }
+
+    /**
+     * Sends a new buffer of pixels to the ImageConsumers 
+     * and notifies them that an animation frame is completed if
+     * the animated flag has been set to true by the setAnimated() method. 
+     */
+    public void newPixels() {
+        newPixels(0, 0, width, height, true);
+    }
+
+    /**
+     * Inits the.
+     * 
+     * @param width the width
+     * @param height the height
+     * @param model the model
+     * @param pixels the pixels
+     * @param off the off
+     * @param scan the scan
+     * @param prop the prop
+     */
+    private void init(int width, int height, ColorModel model, byte pixels[],
+            int off, int scan, Hashtable<?, ?> prop){
+
+        this.width = width;
+        this.height = height;
+        this.cm = model;
+        this.bData = pixels;
+        this.offset = off;
+        this.scanline = scan;
+        this.properties = prop;
+        this.dataType = DATA_TYPE_BYTE;
+        this.consumers = new Vector<ImageConsumer>();
+
+    }
+
+    /**
+     * Inits the.
+     * 
+     * @param width the width
+     * @param height the height
+     * @param model the model
+     * @param pixels the pixels
+     * @param off the off
+     * @param scan the scan
+     * @param prop the prop
+     */
+    private void init(int width, int height, ColorModel model, int pixels[],
+            int off, int scan, Hashtable<?, ?> prop){
+
+        this.width = width;
+        this.height = height;
+        this.cm = model;
+        this.iData = pixels;
+        this.offset = off;
+        this.scanline = scan;
+        this.properties = prop;
+        this.dataType = DATA_TYPE_INT;
+        this.consumers = new Vector<ImageConsumer>();
+    }
+
+    /**
+     * Sets the pixels.
+     * 
+     * @param con the con
+     * @param x the x
+     * @param y the y
+     * @param w the w
+     * @param h the h
+     */
+    private void setPixels(ImageConsumer con, int x, int y, int w, int h){
+        int pixelOff = scanline * y + offset + x;
+
+        switch(dataType){
+        case DATA_TYPE_BYTE:
+            con.setPixels(x, y, w, h, cm, bData, pixelOff, scanline);
+            break;
+        case DATA_TYPE_INT:
+            con.setPixels(x, y, w, h, cm, iData, pixelOff, scanline);
+            break;
+        default:
+            // awt.22A=Wrong type of pixels array
+            throw new IllegalArgumentException(Messages.getString("awt.22A")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Sets the header.
+     * 
+     * @param con the new header
+     */
+    private synchronized void setHeader(ImageConsumer con){
+        con.setDimensions(width, height);
+        con.setProperties(properties);
+        con.setColorModel(cm);
+        con.setHints(animated ? (fullbuffers ? (ImageConsumer.TOPDOWNLEFTRIGHT |
+                ImageConsumer.COMPLETESCANLINES) : ImageConsumer.RANDOMPIXELORDER) :
+                (ImageConsumer.TOPDOWNLEFTRIGHT | ImageConsumer.COMPLETESCANLINES |
+                 ImageConsumer.SINGLEPASS | ImageConsumer.SINGLEFRAME));
+    }
+
+}
+
diff --git a/awt/java/awt/image/MultiPixelPackedSampleModel.java b/awt/java/awt/image/MultiPixelPackedSampleModel.java
new file mode 100644
index 0000000..dd44b49
--- /dev/null
+++ b/awt/java/awt/image/MultiPixelPackedSampleModel.java
@@ -0,0 +1,454 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The MultiPixelPackedSampleModel class represents image data with one
+ * band. This class packs multiple pixels with one sample in one data 
+ * element and supports the following data types: DataBuffer.TYPE_BYTE, 
+ * DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT. 
+ */
+public class MultiPixelPackedSampleModel extends SampleModel {
+
+    /** The pixel bit stride. */
+    private int pixelBitStride;
+
+    /** The scanline stride. */
+    private int scanlineStride;
+
+    /** The data bit offset. */
+    private int dataBitOffset;
+
+    /** The bit mask. */
+    private int bitMask;
+
+    /** The data element size. */
+    private int dataElementSize;
+
+    /** The pixels per data element. */
+    private int pixelsPerDataElement;
+
+    /**
+     * Instantiates a new MultiPixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param numberOfBits the number of bits per pixel.
+     * @param scanlineStride the scanline stride of the of the image data.
+     * @param dataBitOffset the array of the band offsets.
+     */
+    public MultiPixelPackedSampleModel(int dataType, int w, int h,
+            int numberOfBits, int scanlineStride, int dataBitOffset) {
+
+        super(dataType, w, h, 1);
+        if (dataType != DataBuffer.TYPE_BYTE &&
+               dataType != DataBuffer.TYPE_USHORT &&
+               dataType != DataBuffer.TYPE_INT) {
+            // awt.61=Unsupported data type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.61", //$NON-NLS-1$
+                    dataType));
+        }
+
+        this.scanlineStride = scanlineStride;
+        if(numberOfBits == 0) {
+            // awt.20C=Number of Bits equals to zero
+            throw new RasterFormatException(Messages.getString("awt.20C")); //$NON-NLS-1$
+        }
+        this.pixelBitStride = numberOfBits;
+        this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
+        if(dataElementSize % pixelBitStride != 0) {
+            // awt.20D=The number of bits per pixel is not a power of 2 or pixels span data element boundaries
+            throw new RasterFormatException(Messages.getString("awt.20D")); //$NON-NLS-1$
+        }
+
+        if(dataBitOffset % numberOfBits != 0) {
+            // awt.20E=Data Bit offset is not a multiple of pixel bit stride
+            throw new RasterFormatException(Messages.getString("awt.20E")); //$NON-NLS-1$
+        }
+        this.dataBitOffset = dataBitOffset;
+
+        this.pixelsPerDataElement = dataElementSize / pixelBitStride;
+        this.bitMask = (1 << numberOfBits) - 1;
+    }
+
+    /**
+     * Instantiates a new MultiPixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param numberOfBits the number of bits per pixel.
+     */
+    public MultiPixelPackedSampleModel(int dataType, int w, int h,
+            int numberOfBits) {
+
+        this(dataType, w, h, numberOfBits, (numberOfBits * w +
+               DataBuffer.getDataTypeSize(dataType) - 1) /
+               DataBuffer.getDataTypeSize(dataType), 0);
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            if (obj == null) {
+                bdata = new byte[1];
+            } else {
+                bdata = (byte[]) obj;
+            }
+            bdata[0] = (byte) getSample(x, y, 0, data);
+            obj = bdata;
+            break;
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            if (obj == null) {
+                sdata = new short[1];
+            } else {
+                sdata = (short[]) obj;
+            }
+            sdata[0] = (short) getSample(x, y, 0, data);
+            obj = sdata;
+            break;
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            if (obj == null) {
+                idata = new int[1];
+            } else {
+                idata = (int[]) obj;
+            }
+            idata[0] = getSample(x, y, 0, data);
+            obj = idata;
+            break;
+        }
+
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        setSample(x, y, obj, data, 1, 0);
+    }
+
+    /**
+     * Compares this MultiPixelPackedSampleModel object with 
+     * the specified object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if the object is a MultiPixelPackedSampleModel 
+     * with the same data parameter values as this MultiPixelPackedSampleModel,
+     * false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
+            return false;
+        }
+
+        MultiPixelPackedSampleModel model = (MultiPixelPackedSampleModel) o;
+        return this.width == model.width &&
+               this.height == model.height &&
+               this.numBands == model.numBands &&
+               this.dataType == model.dataType &&
+               this.pixelBitStride == model.pixelBitStride &&
+               this.bitMask == model.bitMask &&
+               this.pixelsPerDataElement == model.pixelsPerDataElement &&
+               this.dataElementSize == model.dataElementSize &&
+               this.dataBitOffset == model.dataBitOffset &&
+               this.scanlineStride == model.scanlineStride;
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands != null && bands.length != 1) {
+            // awt.20F=Number of bands must be only 1
+            throw new RasterFormatException(Messages.getString("awt.20F")); //$NON-NLS-1$
+        }
+        return createCompatibleSampleModel(width, height);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        pixel[0] = getSample(x, y, 0, data);
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        setSample(x, y, iArray, data, 2, 0);
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height || b != 0) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int bitnum = dataBitOffset + x * pixelBitStride;
+        int elem = data.getElem(y * scanlineStride + bitnum / dataElementSize);
+        int shift = dataElementSize - (bitnum & (dataElementSize - 1)) -
+                pixelBitStride;
+
+        return (elem >> shift) & bitMask;
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (b != 0) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        setSample(x, y, null, data, 3, s);
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer dataBuffer = null;
+        int size = scanlineStride * height;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            dataBuffer = new DataBufferByte(size + (dataBitOffset + 7) / 8);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            dataBuffer = new DataBufferUShort(size + (dataBitOffset + 15) / 16);
+            break;
+        case DataBuffer.TYPE_INT:
+            dataBuffer = new DataBufferInt(size + (dataBitOffset + 31) / 32);
+            break;
+        }
+        return dataBuffer;
+    }
+
+    /**
+     * Gets the offset of the specified pixel in the data array.
+     * 
+     * @param x the X coordinate of the specified pixel.
+     * @param y the Y coordinate of the specified pixel.
+     * 
+     * @return the offset of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return y * scanlineStride + (x * pixelBitStride + dataBitOffset) /
+               dataElementSize;
+    }
+
+    @Override
+    public int getSampleSize(int band) {
+        return pixelBitStride;
+    }
+
+    /**
+     * Gets the bit offset in the data element which 
+     * is stored for the specified pixel of a scanline.
+     * 
+     * @param x the pixel.
+     * 
+     * @return the bit offset of the pixel in the data element.
+     */
+    public int getBitOffset(int x) {
+        return (x * pixelBitStride + dataBitOffset) % dataElementSize;
+    }
+
+    @Override
+    public int[] getSampleSize() {
+        int sampleSizes[] = { pixelBitStride };
+        return sampleSizes;
+    }
+
+    /**
+     * Returns a hash code of this MultiPixelPackedSampleModel class.
+     * 
+     * @return the hash code of this MultiPixelPackedSampleModel class.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= scanlineStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= pixelBitStride;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataBitOffset;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= bitMask;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataElementSize;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= pixelsPerDataElement;
+        return hash;
+    }
+
+    @Override
+    public int getTransferType() {
+        if (pixelBitStride > 16) {
+            return DataBuffer.TYPE_INT;
+        } else if (pixelBitStride > 8) {
+            return DataBuffer.TYPE_USHORT;
+        } else {
+            return DataBuffer.TYPE_BYTE;
+        }
+    }
+
+    /**
+     * Gets the scanline stride of this MultiPixelPackedSampleModel.
+     * 
+     * @return the scanline stride of this MultiPixelPackedSampleModel.
+     */
+    public int getScanlineStride() {
+        return scanlineStride;
+    }
+
+    /**
+     * Gets the pixel bit stride of this MultiPixelPackedSampleModel.
+     * 
+     * @return the pixel bit stride of this MultiPixelPackedSampleModel.
+     */
+    public int getPixelBitStride() {
+        return pixelBitStride;
+    }
+
+    @Override
+    public int getNumDataElements() {
+        return 1;
+    }
+
+    /**
+     * Gets the data bit offset.
+     * 
+     * @return the data bit offset.
+     */
+    public int getDataBitOffset() {
+        return dataBitOffset;
+    }
+
+    /**
+     * This method is used by other methods of this class. The behaviour of
+     * this method depends on the method which has been invoke this one. The
+     * argument methodId is used to choose valid behaviour in a particular case.
+     * If methodId is equal to 1 it means that this method has been invoked by
+     * the setDataElements() method, 2 - means setPixel(), and setSample() in
+     * any other cases.
+     * 
+     * @param x the x
+     * @param y the y
+     * @param obj the obj
+     * @param data the data
+     * @param methodId the method id
+     * @param s the s
+     */
+    private void setSample(final int x, final int y, final Object obj,
+            final DataBuffer data, final int methodId, int s) {
+        if ((x < 0) || (y < 0) || (x >= this.width) || (y >= this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages
+                    .getString("awt.63")); //$NON-NLS-1$
+        }
+
+        final int bitnum = dataBitOffset + x * pixelBitStride;
+        final int idx = y * scanlineStride + bitnum / dataElementSize;
+        final int shift = dataElementSize - (bitnum & (dataElementSize - 1))
+                - pixelBitStride;
+        final int mask = ~(bitMask << shift);
+        int elem = data.getElem(idx);
+
+        switch (methodId) {
+        case 1: {                        // Invoked from setDataElements()
+            switch (getTransferType()) {
+            case DataBuffer.TYPE_BYTE:
+                s = ((byte[]) obj)[0] & 0xff;
+                break;
+            case DataBuffer.TYPE_USHORT:
+                s = ((short[]) obj)[0] & 0xffff;
+                break;
+            case DataBuffer.TYPE_INT:
+                s = ((int[]) obj)[0];
+                break;
+            }
+            break;
+        }
+        case 2: {                        // Invoked from setPixel()
+            s = ((int[]) obj)[0];
+            break;
+        }
+        }
+
+        elem &= mask;
+        elem |= (s & bitMask) << shift;
+        data.setElem(idx, elem);
+    }
+}
+
diff --git a/awt/java/awt/image/PackedColorModel.java b/awt/java/awt/image/PackedColorModel.java
new file mode 100644
index 0000000..7aaefbf
--- /dev/null
+++ b/awt/java/awt/image/PackedColorModel.java
@@ -0,0 +1,383 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class PackedColorModel represents a color model where the 
+ * components are just the red, green, and blue bands, plus an alpha
+ * band if alpha is supported.
+ */
+public abstract class PackedColorModel extends ColorModel {
+
+    /** The component masks. */
+    int componentMasks[];
+
+    /** The offsets. */
+    int offsets[];
+
+    /** The scales. */
+    float scales[];
+
+    /**
+     * Instantiates a new packed color model.
+     * 
+     * @param space the color space
+     * @param bits the array of component masks
+     * @param colorMaskArray the array that gives the bitmask corresponding
+     * to each color band (red, green, and blue)
+     * @param alphaMask the bitmask corresponding to the alpha band
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this color model
+     * @param trans the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the number of bits in the combined 
+     * bitmasks for the color bands is less than one or greater than 32
+     */
+    public PackedColorModel(ColorSpace space, int bits, int colorMaskArray[],
+            int alphaMask, boolean isAlphaPremultiplied, int trans,
+            int transferType) {
+
+        super(bits, createBits(colorMaskArray, alphaMask), space,
+                (alphaMask == 0 ? false : true), isAlphaPremultiplied, trans,
+                validateTransferType(transferType));
+
+        if (pixel_bits < 1 || pixel_bits > 32) {
+            // awt.236=The bits is less than 1 or greater than 32
+            throw new IllegalArgumentException(Messages.getString("awt.236")); //$NON-NLS-1$
+        }
+
+        componentMasks = new int[numComponents];
+        for (int i = 0; i < numColorComponents; i++) {
+            componentMasks[i] = colorMaskArray[i];
+        }
+
+        if (hasAlpha) {
+            componentMasks[numColorComponents] = alphaMask;
+            if (this.bits[numColorComponents] == 1) {
+                transparency = Transparency.BITMASK;
+            }
+        }
+
+        parseComponents();
+    }
+
+    /**
+     * Instantiates a new packed color model.
+     * 
+     * @param space the color space
+     * @param bits the array of component masks
+     * @param rmask the bitmask corresponding to the red band
+     * @param gmask the bitmask corresponding to the green band
+     * @param bmask the bitmask corresponding to the blue band
+     * @param amask the bitmask corresponding to the alpha band
+     * @param isAlphaPremultiplied whether the alpha is premultiplied in this color model
+     * @param trans the transparency strategy, @see java.awt.Transparency
+     * @param transferType the transfer type (primitive java type 
+     * to use for the components)
+     * 
+     * @throws IllegalArgumentException if the number of bits in the combined 
+     * bitmasks for the color bands is less than one or greater than 32
+     */
+    public PackedColorModel(ColorSpace space, int bits, int rmask, int gmask,
+            int bmask, int amask, boolean isAlphaPremultiplied, int trans,
+            int transferType) {
+
+        super(bits, createBits(rmask, gmask, bmask, amask), space,
+                (amask == 0 ? false : true), isAlphaPremultiplied, trans,
+                validateTransferType(transferType));
+
+        if (pixel_bits < 1 || pixel_bits > 32) {
+            // awt.236=The bits is less than 1 or greater than 32
+            throw new IllegalArgumentException(Messages.getString("awt.236")); //$NON-NLS-1$
+        }
+
+        if (cs.getType() != ColorSpace.TYPE_RGB) {
+            // awt.239=The space is not a TYPE_RGB space
+            throw new IllegalArgumentException(Messages.getString("awt.239")); //$NON-NLS-1$
+        }
+
+        for (int i = 0; i < numColorComponents; i++) {
+            if (cs.getMinValue(i) != 0.0f || cs.getMaxValue(i) != 1.0f) {
+                // awt.23A=The min/max normalized component values are not 0.0/1.0
+                throw new IllegalArgumentException(Messages.getString("awt.23A")); //$NON-NLS-1$
+            }
+        }
+        componentMasks = new int[numComponents];
+        componentMasks[0] = rmask;
+        componentMasks[1] = gmask;
+        componentMasks[2] = bmask;
+
+        if (hasAlpha) {
+            componentMasks[3] = amask;
+            if (this.bits[3] == 1) {
+                transparency = Transparency.BITMASK;
+            }
+        }
+
+        parseComponents();
+    }
+
+    @Override
+    public WritableRaster getAlphaRaster(WritableRaster raster) {
+        if(!hasAlpha) {
+            return null;
+        }
+
+        int x = raster.getMinX();
+        int y = raster.getMinY();
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+        int band[] = new int[1];
+        band[0] = raster.getNumBands() - 1;
+        return raster.createWritableChild(x, y, w, h, x, y, band);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof PackedColorModel)) {
+            return false;
+        }
+        PackedColorModel cm = (PackedColorModel) obj;
+
+        return (pixel_bits == cm.getPixelSize() &&
+                transferType == cm.getTransferType() &&
+                cs.getType() == cm.getColorSpace().getType() &&
+                hasAlpha == cm.hasAlpha() &&
+                isAlphaPremultiplied == cm.isAlphaPremultiplied() &&
+                transparency == cm.getTransparency() &&
+                numColorComponents == cm.getNumColorComponents()&&
+                numComponents == cm.getNumComponents() &&
+                Arrays.equals(bits, cm.getComponentSize()) &&
+                Arrays.equals(componentMasks, cm.getMasks()));
+    }
+
+    @Override
+    public boolean isCompatibleSampleModel(SampleModel sm) {
+        if (sm == null) {
+            return false;
+        }
+        if (!(sm instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+        SinglePixelPackedSampleModel esm = (SinglePixelPackedSampleModel) sm;
+
+        return ((esm.getNumBands() == numComponents) &&
+                (esm.getTransferType() == transferType) &&
+                Arrays.equals(esm.getBitMasks(), componentMasks));
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new SinglePixelPackedSampleModel(transferType, w, h,
+                componentMasks);
+    }
+
+    /**
+     * Gets the bitmask corresponding to the specified color component.
+     * 
+     * @param index the index of the desired color
+     * 
+     * @return the mask
+     */
+    public final int getMask(int index) {
+        return componentMasks[index];
+    }
+
+    /**
+     * Gets the bitmasks of the components.
+     * 
+     * @return the masks
+     */
+    public final int[] getMasks() {
+        return (componentMasks.clone());
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param colorMaskArray the color mask array
+     * @param alphaMask the alpha mask
+     * 
+     * @return the int[]
+     */
+    private static int[] createBits(int colorMaskArray[], int alphaMask) {
+        int bits[];
+        int numComp;
+        if (alphaMask == 0) {
+            numComp = colorMaskArray.length;
+        } else {
+            numComp = colorMaskArray.length + 1;
+        }
+
+        bits = new int[numComp];
+        int i = 0;
+        for (; i < colorMaskArray.length; i++) {
+            bits[i] = countCompBits(colorMaskArray[i]);
+            if (bits[i] < 0) {
+                // awt.23B=The mask of the {0} component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23B", i)); //$NON-NLS-1$
+            }
+        }
+
+        if (i < numComp) {
+            bits[i] = countCompBits(alphaMask);
+
+            if (bits[i] < 0) {
+                // awt.23C=The mask of the alpha component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23C")); //$NON-NLS-1$
+            }
+        }
+
+        return bits;
+    }
+
+    /**
+     * Creates the bits.
+     * 
+     * @param rmask the rmask
+     * @param gmask the gmask
+     * @param bmask the bmask
+     * @param amask the amask
+     * 
+     * @return the int[]
+     */
+    private static int[] createBits(int rmask, int gmask, int bmask,
+            int amask) {
+
+        int numComp;
+        if (amask == 0) {
+            numComp = 3;
+        } else {
+            numComp = 4;
+        }
+        int bits[] = new int[numComp];
+
+        bits[0] = countCompBits(rmask);
+        if (bits[0] < 0) {
+            // awt.23D=The mask of the red component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23D")); //$NON-NLS-1$
+        }
+
+        bits[1] = countCompBits(gmask);
+        if (bits[1] < 0) {
+            // awt.23E=The mask of the green component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23E")); //$NON-NLS-1$
+        }
+
+        bits[2] = countCompBits(bmask);
+        if (bits[2] < 0) {
+            // awt.23F=The mask of the blue component is not contiguous
+            throw new IllegalArgumentException(Messages.getString("awt.23F")); //$NON-NLS-1$
+        }
+
+        if (amask != 0) {
+            bits[3] = countCompBits(amask);
+            if (bits[3] < 0) {
+                // awt.23C=The mask of the alpha component is not contiguous
+                throw new IllegalArgumentException(Messages.getString("awt.23C")); //$NON-NLS-1$
+            }
+        }
+
+        return bits;
+    }
+
+    /**
+     * Count comp bits.
+     * 
+     * @param compMask the comp mask
+     * 
+     * @return the int
+     */
+    private static int countCompBits(int compMask) {
+        int bits = 0;
+        if (compMask != 0) {
+            // Deleting final zeros
+            while ((compMask & 1) == 0) {
+                compMask >>>= 1;
+            }
+            // Counting component bits
+            while ((compMask & 1) == 1) {
+                compMask >>>= 1;
+                bits++;
+            }
+        }
+
+        if (compMask != 0) {
+            return -1;
+        }
+
+        return bits;
+    }
+
+    /**
+     * Validate transfer type.
+     * 
+     * @param transferType the transfer type
+     * 
+     * @return the int
+     */
+    private static int validateTransferType(int transferType) {
+        if (transferType != DataBuffer.TYPE_BYTE &&
+                transferType != DataBuffer.TYPE_USHORT &&
+                transferType != DataBuffer.TYPE_INT) {
+            // awt.240=The transferType not is one of DataBuffer.TYPE_BYTE,
+            //          DataBuffer.TYPE_USHORT or DataBuffer.TYPE_INT
+            throw new IllegalArgumentException(Messages.getString("awt.240")); //$NON-NLS-1$
+        }
+        return transferType;
+}
+
+    /**
+     * Parses the components.
+     */
+    private void parseComponents() {
+        offsets = new int[numComponents];
+        scales = new float[numComponents];
+        for (int i = 0; i < numComponents; i++) {
+            int off = 0;
+            int mask = componentMasks[i];
+            while ((mask & 1) == 0) {
+                mask >>>= 1;
+                off++;
+            }
+            offsets[i] = off;
+            if (bits[i] == 0) {
+                scales[i] = 256.0f; // May be any value different from zero,
+                // because will dividing by zero
+            } else {
+                scales[i] = 255.0f / maxValues[i];
+            }
+        }
+
+    }
+
+}
+
diff --git a/awt/java/awt/image/PixelGrabber.java b/awt/java/awt/image/PixelGrabber.java
new file mode 100644
index 0000000..cecd5c8
--- /dev/null
+++ b/awt/java/awt/image/PixelGrabber.java
@@ -0,0 +1,408 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Image;
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class PixelGrabber implements ImageConsumer {
+
+    int width;
+    int height;
+    int X;
+    int Y;
+    int offset;
+    int scanline;
+    ImageProducer producer;
+
+    byte bData[];
+    int iData[];
+    ColorModel cm;
+
+    private int grabberStatus;
+    private int dataType;
+    private boolean isGrabbing;
+    private boolean isRGB;
+
+
+    private static final int DATA_TYPE_BYTE = 0;
+    private static final int DATA_TYPE_INT = 1;
+    private static final int DATA_TYPE_UNDEFINED = 2;
+
+    private static final int ALL_BITS = (ImageObserver.FRAMEBITS |
+            ImageObserver.ALLBITS);
+
+    private static final int GRABBING_STOP = ALL_BITS | ImageObserver.ERROR;
+
+
+
+    public PixelGrabber(ImageProducer ip, int x, int y, int w, int h, int[] pix,
+            int off, int scansize) {
+        initialize(ip, x, y, w, h, pix, off, scansize, true);
+    }
+
+    public PixelGrabber(Image img, int x, int y, int w, int h, int[] pix,
+            int off, int scansize) {
+        initialize(img.getSource(), x, y, w, h, pix, off, scansize, true);
+    }
+
+    public PixelGrabber(Image img, int x, int y, int w, int h, boolean forceRGB) {
+        initialize(img.getSource(), x, y, w, h, null, 0, 0, forceRGB);
+    }
+
+    public void setProperties(Hashtable<?, ?> props) {
+        return;
+    }
+
+    public synchronized Object getPixels() {
+        switch(dataType){
+        case DATA_TYPE_BYTE:
+            return bData;
+        case DATA_TYPE_INT:
+            return iData;
+        default:
+            return null;
+        }
+    }
+
+    public void setColorModel(ColorModel model) {
+        return;
+    }
+
+    public void setPixels(int srcX, int srcY, int srcW, int srcH,
+            ColorModel model, byte[] pixels, int srcOff, int srcScan) {
+        if(srcY < Y){
+            int delta = Y - srcY;
+            if(delta >= height) {
+                return;
+            }
+            srcY += delta;
+            srcH -= delta;
+            srcOff += srcScan * delta;
+        }
+
+        if(srcY + srcH > Y + height){
+            srcH = Y + height - srcY;
+            if(srcH <= 0) {
+                return;
+            }
+        }
+
+        if(srcX < X){
+            int delta = X - srcX;
+            if(delta >= width) {
+                return;
+            }
+            srcW -= delta;
+            srcX += delta;
+            srcOff += delta;
+        }
+
+        if(srcX + srcW > X + width){
+            srcW = X + width - srcX;
+            if(srcW <= 0) {
+                return;
+            }
+        }
+        if(scanline == 0) {
+            scanline = width;
+        }
+        int realOff = offset + (srcY - Y) * scanline + (srcX - X);
+        switch(dataType){
+        case DATA_TYPE_UNDEFINED:
+            cm = model;
+            if(model != ColorModel.getRGBdefault()){
+                bData = new byte[width * height];
+                isRGB = false;
+                dataType = DATA_TYPE_BYTE;
+            }else{
+                iData = new int[width * height];
+                isRGB = true;
+                dataType = DATA_TYPE_INT;
+            }
+        case DATA_TYPE_BYTE:
+            if(!isRGB && cm == model){
+                for(int y = 0; y < srcH; y++){
+                    System.arraycopy(pixels, srcOff, bData, realOff, srcW);
+                    srcOff += srcScan;
+                    realOff += scanline;
+                }
+                break;
+            }
+            forceToRGB();
+        case DATA_TYPE_INT:
+            for(int y = 0; y < srcH; y++){
+                for(int x = 0; x < srcW; x++){
+                    iData[realOff + x] = cm.getRGB(pixels[srcOff + x] & 0xff);                    
+                }
+                srcOff += srcScan;
+                realOff += scanline;
+            }
+        }
+
+        return;
+    }
+
+    public void setPixels(int srcX, int srcY, int srcW, int srcH,
+            ColorModel model, int[] pixels, int srcOff, int srcScan) {
+
+        if(srcY < Y){
+            int delta = Y - srcY;
+            if(delta >= height) {
+                return;
+            }
+            srcY += delta;
+            srcH -= delta;
+            srcOff += srcScan * delta;
+        }
+
+        if(srcY + srcH > Y + height){
+            srcH = Y + height - srcY;
+            if(srcH <= 0) {
+                return;
+            }
+        }
+
+        if(srcX < X){
+            int delta = X - srcX;
+            if(delta >= width) {
+                return;
+            }
+            srcW -= delta;
+            srcX += delta;
+            srcOff += delta;
+        }
+
+        if(srcX + srcW > X + width){
+            srcW = X + width - srcX;
+            if(srcW <= 0) {
+                return;
+            }
+        }
+        if(scanline == 0) {
+            scanline = width;
+        }
+        int realOff = offset + (srcY - Y) * scanline + (srcX - X);
+
+        int mask = 0xFF;
+
+        switch(dataType){
+        case DATA_TYPE_UNDEFINED:
+            cm = model;
+            iData = new int[width * height];
+            dataType = DATA_TYPE_INT;
+            isRGB = (cm == ColorModel.getRGBdefault());
+
+        case DATA_TYPE_INT:
+            if(cm == model){
+                for(int y = 0; y < srcH; y++){
+                    System.arraycopy(pixels, srcOff, iData, realOff, srcW);
+                    srcOff += srcScan;
+                    realOff += scanline;
+                }
+                break;
+            }
+            mask = 0xFFFFFFFF;
+
+        case DATA_TYPE_BYTE:
+            forceToRGB();
+            for(int y = 0; y < srcH; y++){
+                for(int x = 0; x < srcW; x++){
+                    iData[realOff+x] = cm.getRGB(pixels[srcOff+x] & mask);
+                }
+                srcOff += srcScan;
+                realOff += scanline;
+            }
+        }
+    }
+
+    public synchronized ColorModel getColorModel() {
+        return cm;
+    }
+
+    public synchronized boolean grabPixels(long ms) 
+    throws InterruptedException {
+        if((grabberStatus & GRABBING_STOP) != 0){
+            return ((grabberStatus & ALL_BITS) != 0);
+        }
+
+        long start = System.currentTimeMillis();
+
+        if(!isGrabbing){
+            isGrabbing = true;
+            grabberStatus &= ~ImageObserver.ABORT;
+            producer.startProduction(this);
+        }
+        while((grabberStatus & GRABBING_STOP) == 0){
+            if(ms != 0){
+                ms = start + ms - System.currentTimeMillis();
+                if(ms <= 0) {
+                    break;
+                }
+            }
+            wait(ms);
+        }
+
+        return ((grabberStatus & ALL_BITS) != 0);
+    }
+
+    public void setDimensions(int w, int h) {
+        if(width < 0) {
+            width = w - X;
+        }
+        if(height < 0) {
+            height = h - Y;
+        }
+
+        grabberStatus |= ImageObserver.WIDTH | ImageObserver.HEIGHT;
+
+        if(width <=0 || height <=0){
+            imageComplete(STATICIMAGEDONE);
+            return;
+        }
+
+        if(isRGB && dataType == DATA_TYPE_UNDEFINED){
+            iData = new int[width * height];
+            dataType = DATA_TYPE_INT;
+            scanline = width;
+        }
+    }
+
+    public void setHints(int hints) {
+        return;
+    }
+
+    public synchronized void imageComplete(int status) {
+        switch(status){
+        case IMAGEABORTED:
+            grabberStatus |= ImageObserver.ABORT;
+            break;
+        case IMAGEERROR:
+            grabberStatus |= ImageObserver.ERROR | ImageObserver.ABORT;
+            break;
+        case SINGLEFRAMEDONE:
+            grabberStatus |= ImageObserver.FRAMEBITS;
+            break;
+        case STATICIMAGEDONE:
+            grabberStatus |= ImageObserver.ALLBITS;
+            break;
+        default:
+            // awt.26A=Incorrect ImageConsumer completion status
+            throw new IllegalArgumentException(Messages.getString("awt.26A")); //$NON-NLS-1$
+        }
+        isGrabbing = false;
+        producer.removeConsumer(this);
+        notifyAll();
+    }
+
+    public boolean grabPixels() throws InterruptedException {
+        return grabPixels(0);
+    }
+
+    public synchronized void startGrabbing() {
+        if((grabberStatus & GRABBING_STOP) != 0){
+            return;
+        }
+        if(!isGrabbing){
+            isGrabbing = true;
+            grabberStatus &= ~ImageObserver.ABORT;
+            producer.startProduction(this);
+        }
+    }
+
+    public synchronized void abortGrabbing() {
+        imageComplete(IMAGEABORTED);
+    }
+
+    public synchronized int status() {
+        return grabberStatus;
+    }
+
+    public synchronized int getWidth() {
+        if(width < 0) {
+            return -1;
+        }
+        return width;
+    }
+
+    public synchronized int getStatus() {
+        return grabberStatus;
+    }
+
+    public synchronized int getHeight() {
+        if(height < 0) {
+            return -1;
+        }
+        return height;
+    }
+
+    private void initialize(ImageProducer ip, int x, int y, int w, int h,
+            int pixels[], int off, int scansize, boolean forceRGB){
+
+        producer = ip;
+        X = x;
+        Y = y;
+        width = w;
+        height = h;
+        iData = pixels;
+        dataType = (pixels == null) ? DATA_TYPE_UNDEFINED : DATA_TYPE_INT;
+        offset = off;
+        scanline = scansize;
+        if(forceRGB){
+            cm = ColorModel.getRGBdefault();
+            isRGB = true;
+        }
+    }
+
+    /**
+     * Force pixels to INT RGB mode
+     */
+    private void forceToRGB(){
+        if (isRGB)
+            return;
+    
+        switch(dataType){
+        case DATA_TYPE_BYTE:
+            iData = new int[width * height];
+            for(int i = 0; i < iData.length; i++){
+                iData[i] = cm.getRGB(bData[i] & 0xff);
+            }
+            dataType = DATA_TYPE_INT;
+            bData = null;
+            break;
+
+        case DATA_TYPE_INT:
+            int buff[] = new int[width * height];
+            for(int i = 0; i < iData.length; i++){
+                buff[i] = cm.getRGB(iData[i]);
+            }
+            iData = buff;
+            break;
+        }
+        offset = 0;
+        scanline = width;
+        cm = ColorModel.getRGBdefault();
+        isRGB = true;
+    }
+
+}
diff --git a/awt/java/awt/image/PixelInterleavedSampleModel.java b/awt/java/awt/image/PixelInterleavedSampleModel.java
new file mode 100644
index 0000000..e41473e
--- /dev/null
+++ b/awt/java/awt/image/PixelInterleavedSampleModel.java
@@ -0,0 +1,124 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The PixelInterleavedSampleModel class represents image data 
+ * as represented as interleaved pixels and for which each sample of 
+ * a pixel takes one data element of the DataBuffer.
+ */
+public class PixelInterleavedSampleModel extends ComponentSampleModel {
+
+    /**
+     * Instantiates a new PixelInterleavedSampleModel with the 
+     * specified parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param pixelStride the pixel stride of the image data.
+     * @param scanlineStride the scanline stride of the of the image data.
+     * @param bandOffsets the array of the band offsets.
+     */
+    public PixelInterleavedSampleModel(int dataType, int w, int h,
+            int pixelStride, int scanlineStride, int bandOffsets[]) {
+
+        super(dataType, w, h, pixelStride, scanlineStride, bandOffsets);
+
+        int maxOffset = bandOffsets[0];
+        int minOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+
+        maxOffset -= minOffset;
+
+        if (maxOffset > scanlineStride) {
+            // awt.241=Any offset between bands is greater than the Scanline stride
+            throw new IllegalArgumentException(Messages.getString("awt.241")); //$NON-NLS-1$
+        }
+
+        if (maxOffset > pixelStride) {
+            // awt.242=Pixel stride is less than any offset between bands
+            throw new IllegalArgumentException(Messages.getString("awt.242")); //$NON-NLS-1$
+        }
+
+        if (pixelStride * w > scanlineStride) {
+            // awt.243=Product of Pixel stride and w is greater than Scanline stride
+            throw new IllegalArgumentException(Messages.getString("awt.243")); //$NON-NLS-1$
+        }
+
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        int newOffsets[] = new int[bands.length];
+        for (int i = 0; i < bands.length; i++) {
+            newOffsets[i] = bandOffsets[bands[i]];
+        }
+
+        return new PixelInterleavedSampleModel(dataType, width, height,
+                pixelStride, scanlineStride, newOffsets);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        int newOffsets[];
+        int minOffset = bandOffsets[0];
+
+        for (int i = 1; i < numBands; i++) {
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+
+        if (minOffset > 0) {
+            newOffsets = new int[numBands];
+            for (int i = 0; i < numBands; i++) {
+                newOffsets[i] = bandOffsets[i] - minOffset;
+            }
+        } else {
+            newOffsets = bandOffsets;
+        }
+
+        return new PixelInterleavedSampleModel(dataType, w, h, pixelStride,
+                pixelStride * w, newOffsets);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = super.hashCode();
+        int tmp = hash >>> 8;
+        hash <<= 8;
+        hash |= tmp;
+
+        return hash ^ 0x66;
+    }
+
+}
+
diff --git a/awt/java/awt/image/RGBImageFilter.java b/awt/java/awt/image/RGBImageFilter.java
new file mode 100644
index 0000000..9a76997
--- /dev/null
+++ b/awt/java/awt/image/RGBImageFilter.java
@@ -0,0 +1,190 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * The RGBImageFilter class represents a filter which modifies
+ * pixels of an image in the default RGB ColorModel. 
+ */
+public abstract class RGBImageFilter extends ImageFilter {
+
+    /** 
+     * The origmodel is the ColorModel to be replaced by newmodel 
+     * when substituteColorModel is called.
+     */
+    protected ColorModel origmodel;
+
+    /** 
+     * The newmodel is the ColorModel with which to replace origmodel 
+     * when substituteColorModel is called. 
+     */
+    protected ColorModel newmodel;
+
+    /** 
+     * The canFilterIndexColorModel indicates if it is 
+     * acceptable to apply the color filtering of the filterRGB 
+     * method to the color table entries of an IndexColorModel 
+     * object.
+     * */
+    protected boolean canFilterIndexColorModel;
+
+    /**
+     * Instantiates a new RGBImageFilter.
+     */
+    public RGBImageFilter() {}
+
+    /**
+     * Filters an IndexColorModel object by calling filterRGB function for
+     * each entry of IndexColorModel.
+     * 
+     * @param icm the IndexColorModel to be filtered.
+     * 
+     * @return the IndexColorModel.
+     */
+    public IndexColorModel filterIndexColorModel(IndexColorModel icm) {
+        int transferType = icm.getTransferType();
+        int bits = icm.getPixelSize();
+        int mapSize = icm.getMapSize();
+        int colorMap[] = new int[mapSize];
+        int filteredColorMap[] = new int[mapSize];
+        icm.getRGBs(colorMap);
+        int trans = -1;
+        boolean hasAlpha = false;
+        for(int i = 0; i < mapSize; i++){
+            filteredColorMap[i] = filterRGB(-1, -1, colorMap[i]);
+            int alpha = filteredColorMap[i] >>> 24;
+            if(alpha != 0xff){
+                if(!hasAlpha) {
+                    hasAlpha = true;
+                }
+                if(alpha == 0 && trans < 0) {
+                    trans = i;
+                }
+            }
+        }
+
+        return new IndexColorModel(bits, mapSize, filteredColorMap, 0,
+                hasAlpha, trans, transferType);
+    }
+
+    /**
+     * Replaces the original color model and the new one.
+     * 
+     * @param oldcm the old ColorModel.
+     * @param newcm the new ColorModel.
+     */
+    public void substituteColorModel(ColorModel oldcm, ColorModel newcm) {
+        origmodel = oldcm;
+        newmodel = newcm;
+    }
+
+    @Override
+    public void setColorModel(ColorModel model) {
+        if(model instanceof IndexColorModel &&
+                canFilterIndexColorModel){
+            IndexColorModel icm = (IndexColorModel) model;
+            ColorModel filteredModel = filterIndexColorModel(icm);
+            substituteColorModel(model, filteredModel);
+            consumer.setColorModel(filteredModel);
+        }else{
+            consumer.setColorModel(ColorModel.getRGBdefault());
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, 
+            int[] pixels, int off, int scansize) {
+        
+        if(model == null || model == origmodel){
+            consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
+        }else{
+            int rgbPixels[] = new int[w];
+            for(int sy = y, pixelsOff = off; sy < y + h; 
+                sy++, pixelsOff += scansize){
+                
+                for(int sx = x, idx = 0; sx < x + w; sx++, idx++){
+                    rgbPixels[idx] = model.getRGB(pixels[pixelsOff + idx]);
+                }
+                filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w);
+            }
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, ColorModel model, 
+            byte[] pixels, int off, int scansize) {
+        
+        if(model == null || model == origmodel){
+            consumer.setPixels(x, y, w, h, newmodel, pixels, off, scansize);
+        }else{
+            int rgbPixels[] = new int[w];
+            for(int sy = y, pixelsOff = off; sy < y + h; 
+                sy++, pixelsOff += scansize){
+                
+                for(int sx = x, idx = 0; sx < x + w; sx++, idx++){
+                    rgbPixels[idx] = 
+                        model.getRGB(pixels[pixelsOff + idx] & 0xff);
+                }
+                filterRGBPixels(x, sy, w, 1, rgbPixels, 0, w);
+            }
+        }
+    }
+
+    /**
+     * Filters a region of pixels in the default RGB ColorModel 
+     * by calling the filterRGB method for them.
+     * 
+     * @param x the X coordinate of region.
+     * @param y the Y coordinate of region.
+     * @param w the width ofregion.
+     * @param h the height of region.
+     * @param pixels the pixels array.
+     * @param off the offset of array.
+     * @param scansize the distance between rows of pixels in the array.
+     */
+    public void filterRGBPixels(int x, int y, int w, int h, 
+            int[] pixels, int off, int scansize) {
+        
+        for(int sy = y, lineOff = off; sy < y + h; sy++, lineOff += scansize){
+            for(int sx = x, idx = 0; sx < x + w; sx++, idx++){
+                pixels[lineOff + idx] = 
+                    filterRGB(sx, sy, pixels[lineOff + idx]);
+            }
+        }
+        consumer.setPixels(x, y, w, h, ColorModel.getRGBdefault(), 
+                pixels, off, scansize);
+    }
+
+    /**
+     * Coverts a single input pixel in the default RGB ColorModel 
+     * to a single output pixel.
+     * 
+     * @param x the X pixel's coordinate.
+     * @param y the Y pixel's coordinate.
+     * @param rgb a pixel in the default RGB color model.
+     * 
+     * @return a filtered pixel in the default RGB color model.
+     */
+    public abstract int filterRGB(int x, int y, int rgb);
+
+}
+
diff --git a/awt/java/awt/image/Raster.java b/awt/java/awt/image/Raster.java
new file mode 100644
index 0000000..4b2426e
--- /dev/null
+++ b/awt/java/awt/image/Raster.java
@@ -0,0 +1,1412 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.gl.image.OrdinaryWritableRaster;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Raster class represents a rectangular area of pixels.
+ * This class is defined by DataBuffer and SampleModel objects. 
+ * The DataBuffer object stores sample values and DSampleModel defines 
+ * the location of sample in this DataBuffer. 
+ */
+public class Raster {
+
+    /** The DataBuffer of this Raster. */
+    protected DataBuffer dataBuffer;
+
+    /** The height of this Raster. */
+    protected int height;
+
+    /** The X coordinate of the upper left pixel in this Raster. */
+    protected int minX;
+
+    /** The Y coordinate of the upper left pixel in this Raster. */
+    protected int minY;
+
+    /** The number of bands in this Raster. */
+    protected int numBands;
+
+    /** The number of data elements. */
+    protected int numDataElements;
+
+    /** The parent of this Raster. */
+    protected Raster parent;
+
+    /** The SampleModel of this Raster. */
+    protected SampleModel sampleModel;
+
+    /** 
+     * The X translation from the coordinate space of the 
+     * SampleModel of this Raster.
+     */
+    protected int sampleModelTranslateX;
+
+    /** 
+     * The Y translation from the coordinate space of the 
+     * SampleModel of this Raster.
+     */
+    protected int sampleModelTranslateY;
+
+    /** The width of this Raster. */
+    protected int width;
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified 
+     * DataBuffer. The number of bands is defined by the length of bandOffsets
+     * or bankIndices arrays.
+     * 
+     * @param dataBuffer the specified DataBuffer.
+     * @param w the width of the image data.
+     * @param h the height of the image data. 
+     * @param bankIndices the bank indices of bands.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
+            int w, int h, int scanlineStride, int bankIndices[],
+            int bandOffsets[], Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bankIndices == null || bandOffsets == null) {
+            // awt.277=bankIndices or bandOffsets is null
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.277")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        BandedSampleModel sampleModel = new BandedSampleModel(dataType, w, h,
+                scanlineStride, bankIndices, bandOffsets);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+    }
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified
+     * data type. The Data type can be one of the following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of the samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data. 
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bankIndices the bank indices of bands.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(int dataType, int w, int h,
+            int scanlineStride, int bankIndices[], int bandOffsets[],
+            Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bankIndices == null || bandOffsets == null) {
+            // awt.277=bankIndices or bandOffsets is null
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.277")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        int maxOffset = bandOffsets[0];
+        int maxBank = bankIndices[0];
+
+        for (int i = 0; i < bankIndices.length; i++) {
+            if (bandOffsets[i] > maxOffset) {
+                maxOffset = bandOffsets[i];
+            }
+            if (bankIndices[i] > maxBank) {
+                maxBank = bankIndices[i];
+            }
+        }
+
+        int numBanks = maxBank + 1;
+        int dataSize = scanlineStride * (h - 1) + w + maxOffset;
+
+        DataBuffer data = null;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(dataSize, numBanks);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(dataSize, numBanks);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(dataSize, numBanks);
+            break;
+        }
+        return createBandedRaster(data, w, h, scanlineStride, bankIndices,
+                bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a BandedSampleModel and the specified
+     * data type. The Data type can be one of the following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of the samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data. 
+     * @param bands the number of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createBandedRaster(int dataType, int w, int h,
+            int bands, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bands < 1) {
+            // awt.279=bands is less than 1
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.279")); //$NON-NLS-1$
+        }
+
+        int bandOffsets[] = new int[bands];
+        int bankIndices[] = new int[bands];
+
+        for (int i = 0; i < bands; i++) {
+            bandOffsets[i] = 0;
+            bankIndices[i] = i;
+        }
+        return createBandedRaster(dataType, w, h, w, bankIndices, bandOffsets,
+                location);
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel 
+     * and the specified DataBuffer. 
+     * 
+     * @param dataBuffer the DataBuffer.
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param pixelStride the pixel stride of image data.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
+            int w, int h, int scanlineStride, int pixelStride,
+            int bandOffsets[], Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        if (bandOffsets == null) {
+            // awt.27B=bandOffsets is null
+            throw new NullPointerException(Messages.getString("awt.27B")); //$NON-NLS-1$
+        }
+
+        PixelInterleavedSampleModel sampleModel = 
+            new PixelInterleavedSampleModel(dataType, w, h, 
+                    pixelStride, scanlineStride, bandOffsets);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel 
+     * and the specified data type. The Data type can be one of the 
+     * following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of the samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param pixelStride the pixel stride of image data.
+     * @param bandOffsets the band offsets of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster object.
+     */
+    public static WritableRaster createInterleavedRaster(int dataType, int w,
+            int h, int scanlineStride, int pixelStride, int bandOffsets[],
+            Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (bandOffsets == null) {
+            // awt.27B=bandOffsets is null
+            throw new NullPointerException(Messages.getString("awt.27B")); //$NON-NLS-1$
+        }
+
+        int minOffset = bandOffsets[0];
+        for (int i = 1; i < bandOffsets.length; i++) {
+            if (bandOffsets[i] < minOffset) {
+                minOffset = bandOffsets[i];
+            }
+        }
+        int size = (h - 1) * scanlineStride + w * pixelStride + minOffset;
+        DataBuffer data = null;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size);
+            break;
+        }
+
+        return createInterleavedRaster(data, w, h, scanlineStride, pixelStride,
+                bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a PixelInterleavedSampleModel 
+     * and the specified data type. The Data type can be one of the 
+     * following values:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * 
+     * @param dataType the data type of samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of image data.
+     * @param h the height of image data.
+     * @param bands the number of bands.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createInterleavedRaster(int dataType, int w,
+            int h, int bands, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        int bandOffsets[] = new int[bands];
+        for (int i = 0; i < bands; i++) {
+            bandOffsets[i] = i;
+        }
+
+        return createInterleavedRaster(dataType, w, h, w * bands, bands,
+                bandOffsets, location);
+    }
+
+    /**
+     * Creates a Raster object with a SinglePixelPackedSampleModel  
+     * and the specified DataBuffer. 
+     * 
+     * @param dataBuffer the DataBuffer.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param scanlineStride the scanline stride of the image data.
+     * @param bandMasks the band masks.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
+            int w, int h, int scanlineStride, int bandMasks[], Point location) {
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bandMasks == null) {
+            // awt.27C=bandMasks is null
+            throw new RasterFormatException(Messages.getString("awt.27C")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        SinglePixelPackedSampleModel sampleModel = 
+            new SinglePixelPackedSampleModel(dataType, w, h, 
+                    scanlineStride, bandMasks);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+    }
+
+    /**
+     * Creates a Raster object with a MultiPixelPackedSampleModel   
+     * and the specified DataBuffer.
+     * 
+     * @param dataBuffer the DataBuffer.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bitsPerPixel the number of bits per pixel.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
+            int w, int h, int bitsPerPixel, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer == null) {
+            // awt.278=dataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.278")); //$NON-NLS-1$
+        }
+
+        if (dataBuffer.getNumBanks() > 1) {
+            // awt.27A=dataBuffer has more than one bank
+            throw new RasterFormatException(Messages.getString("awt.27A")); //$NON-NLS-1$
+        }
+
+        int dataType = dataBuffer.getDataType();
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        MultiPixelPackedSampleModel sampleModel = 
+            new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);
+
+        return new OrdinaryWritableRaster(sampleModel, dataBuffer, location);
+
+    }
+
+    /**
+     * Creates a Raster object with a MultiPixelPackedSampleModel   
+     * and the specified DataBuffer.
+     * 
+     * @param dataType the data type of samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bands the number of bands.
+     * @param bitsPerBand the number of bits per band.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(int dataType, int w, int h,
+            int bands, int bitsPerBand, Point location) {
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bands < 1 || bitsPerBand < 1) {
+            // awt.27D=bitsPerBand or bands is not greater than zero
+            throw new IllegalArgumentException(Messages.getString("awt.27D")); //$NON-NLS-1$
+        }
+
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (bitsPerBand * bands > DataBuffer.getDataTypeSize(dataType)) {
+            // awt.27E=The product of bitsPerBand and bands is greater than the number of bits held by dataType
+            throw new IllegalArgumentException(Messages.getString("awt.27E")); //$NON-NLS-1$
+        }
+
+        if (bands > 1) {
+
+            int bandMasks[] = new int[bands];
+            int mask = (1 << bitsPerBand) - 1;
+
+            for (int i = 0; i < bands; i++) {
+                bandMasks[i] = mask << (bitsPerBand * (bands - 1 - i));
+            }
+
+            return createPackedRaster(dataType, w, h, bandMasks, location);
+        }
+        DataBuffer data = null;
+        int size = ((bitsPerBand * w + 
+                DataBuffer.getDataTypeSize(dataType) - 1) / 
+                DataBuffer.getDataTypeSize(dataType)) * h;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size);
+            break;
+        }
+        return createPackedRaster(data, w, h, bitsPerBand, location);
+    }
+
+    /**
+     * Creates a Raster object with a SinglePixelPackedSampleModel    
+     * and the specified DataBuffer.
+     * 
+     * @param dataType the data type of samples:
+     * TYPE_BYTE, TYPE_USHORT, or TYPE_INT. 
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bandMasks the band masks.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createPackedRaster(int dataType, int w, int h,
+            int bandMasks[], Point location) {
+        
+        if (dataType != DataBuffer.TYPE_BYTE
+                && dataType != DataBuffer.TYPE_USHORT
+                && dataType != DataBuffer.TYPE_INT) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        if ((long) location.x + w > Integer.MAX_VALUE
+                || (long) location.y + h > Integer.MAX_VALUE) {
+            // awt.276=location.x + w or location.y + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.276")); //$NON-NLS-1$
+        }
+
+        if (bandMasks == null) {
+            // awt.27C=bandMasks is null
+            throw new NullPointerException(Messages.getString("awt.27C")); //$NON-NLS-1$
+        }
+
+        DataBuffer data = null;
+
+        switch (dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(w * h);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(w * h);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(w * h);
+            break;
+        }
+
+        return createPackedRaster(data, w, h, w, bandMasks, location);
+    }
+
+    /**
+     * Creates a Raster object with the specified DataBuffer and SampleModel.
+     * 
+     * @param sm the specified SampleModel.
+     * @param db the specified DataBuffer.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the Raster.
+     */
+    public static Raster createRaster(SampleModel sm, DataBuffer db,
+            Point location) {
+
+        if (sm == null || db == null) {
+            // awt.27F=SampleModel or DataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.27F")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return new Raster(sm, db, location);
+    }
+
+    /**
+     * Creates a WritableRaster with the specified SampleModel and DataBuffer.
+     * 
+     * @param sm the specified SampleModel.
+     * @param db the specified DataBuffer.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createWritableRaster(SampleModel sm,
+            DataBuffer db, Point location) {
+
+        if (sm == null || db == null) {
+            // awt.27F=SampleModel or DataBuffer is null
+            throw new NullPointerException(Messages.getString("awt.27F")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return new OrdinaryWritableRaster(sm, db, location);
+    }
+
+    /**
+     * Creates a WritableRaster with the specified SampleModel.
+     * 
+     * @param sm the specified SampleModel.
+     * @param location the location which defines the upper left corner 
+     * of the Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public static WritableRaster createWritableRaster(SampleModel sm,
+            Point location) {
+
+        if (sm == null) {
+            // awt.280=SampleModel is null
+            throw new NullPointerException(Messages.getString("awt.280")); //$NON-NLS-1$
+        }
+
+        if (location == null) {
+            location = new Point(0, 0);
+        }
+
+        return createWritableRaster(sm, sm.createDataBuffer(), location);
+    }
+
+    /**
+     * Instantiates a new Raster object with the specified SampleModel and
+     * DataBuffer.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified  DataBuffer.
+     * @param origin the specified origin.
+     */
+    protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Point origin) {
+
+        this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
+                sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
+    }
+
+    /**
+     * Instantiates a new Raster object with the specified SampleModel,
+     * DataBuffer, rectangular region and parent Raster. 
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified DataBuffer.
+     * @param aRegion the a rectangular region which defines the new image bounds. 
+     * @param sampleModelTranslate this point defines the translation point
+     * from the SampleModel coordinates to the new Raster coordinates.
+     * @param parent the parent of this Raster.
+     */
+    protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Rectangle aRegion, Point sampleModelTranslate, Raster parent) {
+
+        if (sampleModel == null || dataBuffer == null || aRegion == null
+                || sampleModelTranslate == null) {
+            // awt.281=sampleModel, dataBuffer, aRegion or sampleModelTranslate is null
+            throw new NullPointerException(Messages.getString("awt.281")); //$NON-NLS-1$
+        }
+
+        if (aRegion.width <= 0 || aRegion.height <= 0) {
+            // awt.282=aRegion has width or height less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.282")); //$NON-NLS-1$
+        }
+
+        if ((long) aRegion.x + (long) aRegion.width > Integer.MAX_VALUE) {
+            // awt.283=Overflow X coordinate of Raster
+            throw new RasterFormatException(Messages.getString("awt.283")); //$NON-NLS-1$
+        }
+
+        if ((long) aRegion.y + (long) aRegion.height > Integer.MAX_VALUE) {
+            // awt.284=Overflow Y coordinate of Raster
+            throw new RasterFormatException(Messages.getString("awt.284")); //$NON-NLS-1$
+        }
+        
+        if (sampleModel instanceof ComponentSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((ComponentSampleModel) sampleModel).getScanlineStride());
+        } else if (sampleModel instanceof MultiPixelPackedSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((MultiPixelPackedSampleModel) sampleModel)
+                            .getScanlineStride());
+        } else if (sampleModel instanceof SinglePixelPackedSampleModel) {
+            validateDataBuffer(dataBuffer, aRegion.width, aRegion.height,
+                    ((SinglePixelPackedSampleModel) sampleModel)
+                            .getScanlineStride());
+        }
+
+        this.sampleModel = sampleModel;
+        this.dataBuffer = dataBuffer;
+        this.minX = aRegion.x;
+        this.minY = aRegion.y;
+        this.width = aRegion.width;
+        this.height = aRegion.height;
+        this.sampleModelTranslateX = sampleModelTranslate.x;
+        this.sampleModelTranslateY = sampleModelTranslate.y;
+        this.parent = parent;
+        this.numBands = sampleModel.getNumBands();
+        this.numDataElements = sampleModel.getNumDataElements();
+
+    }
+
+    /**
+     * Instantiates a new Raster with the specified SampleModel.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param origin the origin.
+     */
+    protected Raster(SampleModel sampleModel, Point origin) {
+        this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(
+                origin.x, origin.y, sampleModel.getWidth(), sampleModel
+                        .getHeight()), origin, null);
+    }
+
+    /**
+     * Creates the child of this Raster by sharing the specified rectangular
+     * area in this Raste. The parentX, parentY, width 
+     * and height parameters specify the rectangular area to be shared.
+     * 
+     * @param parentX the X coordinate of the upper left corner of this Raster. 
+     * @param parentY the Y coordinate of the upper left corner of this Raster.
+     * @param width the width of the child area.
+     * @param height the height of the child area.
+     * @param childMinX the X coordinate of child area mapped to the parentX
+     * coordinate.
+     * @param childMinY the Y coordinate of child area mapped to the parentY
+     * coordinate.
+     * @param bandList the array of band indicies.
+     * 
+     * @return the Raster.
+     */
+    public Raster createChild(int parentX, int parentY, int width, int height,
+            int childMinX, int childMinY, int bandList[]) {
+        if (width <= 0 || height <= 0) {
+            // awt.285=Width or Height of child Raster is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.285")); //$NON-NLS-1$
+        }
+
+        if (parentX < this.minX || parentX + width > this.minX + this.width) {
+            // awt.286=parentX disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.286")); //$NON-NLS-1$
+        }
+
+        if (parentY < this.minY || parentY + height > this.minY + this.height) {
+            // awt.287=parentY disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.287")); //$NON-NLS-1$
+        }
+
+        if ((long) parentX + width > Integer.MAX_VALUE) {
+            // awt.288=parentX + width results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.288")); //$NON-NLS-1$
+        }
+
+        if ((long) parentY + height > Integer.MAX_VALUE) {
+            // awt.289=parentY + height results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.289")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinX + width > Integer.MAX_VALUE) {
+            // awt.28A=childMinX + width results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.28A")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinY + height > Integer.MAX_VALUE) {
+            // awt.28B=childMinY + height results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.28B")); //$NON-NLS-1$
+        }
+
+        SampleModel childModel;
+
+        if (bandList == null) {
+            childModel = sampleModel;
+        } else {
+            childModel = sampleModel.createSubsetSampleModel(bandList);
+        }
+
+        int childTranslateX = childMinX - parentX;
+        int childTranslateY = childMinY - parentY;
+
+        return new Raster(childModel, dataBuffer, new Rectangle(childMinX,
+                childMinY, width, height), new Point(childTranslateX
+                + sampleModelTranslateX, childTranslateY
+                + sampleModelTranslateY), this);
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster() {
+        return new OrdinaryWritableRaster(sampleModel, new Point(0, 0));
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster and the specified size.
+     * 
+     * @param w the width of the new WritableRaster.
+     * @param h the height of the new WritableRaster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(int w, int h) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
+
+        return new OrdinaryWritableRaster(sm, new Point(0, 0));
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster and the specified size and location.
+     * 
+     * @param x the X coordinate of the new WritableRaster.
+     * @param y the Y coordinate of the new WritableRaster.
+     * @param w the width of the new WritableRaster.
+     * @param h the height of the new WritableRaster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(int x, int y, int w,
+            int h) {
+
+        WritableRaster raster = createCompatibleWritableRaster(w, h);
+
+        return raster.createWritableChild(0, 0, w, h, x, y, null);
+    }
+
+    /**
+     * Create a compatible WritableRaster with the same parameters 
+     * as this Raster and the specified rectangle which determines
+     * new WritableRaster's location and size.
+     * 
+     * @param rect the specified Rectangle.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleWritableRaster(Rectangle rect) {
+        if (rect == null) {
+            // awt.28C=Rect is null
+            throw new NullPointerException(Messages.getString("awt.28C")); //$NON-NLS-1$
+        }
+
+        return createCompatibleWritableRaster(rect.x, rect.y, rect.width,
+                rect.height);
+    }
+
+    /**
+     * Creates the translated child of this Raster. The New Raster
+     * object is a reference to the this Raster with a 
+     * different location. 
+     *  
+     * @param childMinX the X coordinate of the new Raster.
+     * @param childMinY the Y coordinate of the new Raster.
+     * 
+     * @return the Raster.
+     */
+    public Raster createTranslatedChild(int childMinX, int childMinY) {
+        return createChild(minX, minY, width, height, childMinX, childMinY,
+                null);
+    }
+
+    /**
+     * Gets the bounds of this Raster as a rectangle.
+     * 
+     * @return the bounds of this Raster.
+     */
+    public Rectangle getBounds() {
+        return new Rectangle(minX, minY, width, height);
+    }
+
+    /**
+     * Gets the DataBuffer associated with this Raster.
+     * 
+     * @return the DataBuffer associated with this Raster.
+     */
+    public DataBuffer getDataBuffer() {
+        return dataBuffer;
+    }
+
+    /**
+     * Gets the data elements which represent the pixel data of the specified 
+     * rectangle area as a primitive array. The following image data types
+     * are supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 
+     * or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param outData the resulting array.
+     * 
+     * @return the data elements of the specified area of this Raster.
+     */
+    public Object getDataElements(int x, int y, int w, int h, Object outData) {
+        return sampleModel.getDataElements(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, outData, dataBuffer);
+    }
+
+    /**
+     * Gets the data elements which represent the specified pixel of 
+     * this Raster as a primitive array. The following image data types
+     * are supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 
+     * or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param outData the resulting data.
+     * 
+     * @return the data elements of the specified pixel of this Raster.
+     */
+    public Object getDataElements(int x, int y, Object outData) {
+        return sampleModel.getDataElements(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, outData, dataBuffer);
+    }
+
+    /**
+     * Gets the height of this Raster.
+     * 
+     * @return the height of this Raster.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the minimum X coordinate of this Raster.
+     * 
+     * @return the minimum X coordinate of this Raster.
+     */
+    public final int getMinX() {
+        return minX;
+    }
+
+    /**
+     * Gets the minimum Y coordinate of this Raster.
+     * 
+     * @return the minimum Y coordinate of this Raster.
+     */
+    public final int getMinY() {
+        return minY;
+    }
+
+    /**
+     * Gets the number of bands in this Raster.
+     * 
+     * @return the number of bands in this Raster.
+     */
+    public final int getNumBands() {
+        return numBands;
+    }
+
+    /**
+     * Gets the number of data elements for one pixel.
+     * 
+     * @return the number of data elements for one pixel.
+     */
+    public final int getNumDataElements() {
+        return numDataElements;
+    }
+
+    /**
+     * Gets the parent Raster for this Raster object. 
+     * 
+     * @return the parent Raster for this Raster object.
+     */
+    public Raster getParent() {
+        return parent;
+    }
+
+    /**
+     * Gets a double array of samples for the specified pixel in this Raster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param dArray the double array where result array will be stored.
+     * 
+     * @return the double array of samples for the specified pixel in 
+     * this Raster.
+     */
+    public double[] getPixel(int x, int y, double dArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, dArray, dataBuffer);
+    }
+
+    /**
+     * Gets a float array of samples for the specified pixel in this Raster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param fArray the float array where the result array will be stored.
+     * 
+     * @return the float array of samples for the specified pixel in 
+     * this Raster.
+     */
+    public float[] getPixel(int x, int y, float fArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, fArray, dataBuffer);
+    }
+
+    /**
+     * Gets an int array of samples for the specified pixel in this Raster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param iArray the int array where the result array will be stored.
+     * 
+     * @return the int array of samples for the specified pixel in 
+     * this Raster.
+     */
+    public int[] getPixel(int x, int y, int iArray[]) {
+        return sampleModel.getPixel(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, iArray, dataBuffer);
+    }
+
+    /**
+     * Gets an double array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param dArray the resulting array.
+     * 
+     * @return the double array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     */
+    public double[] getPixels(int x, int y, int w, int h, double dArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, dArray, dataBuffer);
+    }
+
+    /**
+     * Gets an float array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param fArray the resulting array.
+     * 
+     * @return the float array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     */
+    public float[] getPixels(int x, int y, int w, int h, float fArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, fArray, dataBuffer);
+    }
+
+    /**
+     * Gets an int array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of pixel's the area of pixels.
+     * @param h the height of pixel's the area of pixels.
+     * @param iArray the resulting array.
+     * 
+     * @return the int array of samples for the specified rectangular
+     * area of pixels in this Raster.
+     */
+    public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
+        return sampleModel.getPixels(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, iArray, dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified
+     * pixel as an int.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the sample for the specified band of the specified
+     * pixel as an int.
+     */
+    public int getSample(int x, int y, int b) {
+        return sampleModel.getSample(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, b, dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified
+     * pixel as a double.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the sample for the specified band of the specified
+     * pixel as a double.
+     */
+    public double getSampleDouble(int x, int y, int b) {
+        return sampleModel.getSampleDouble(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, b, dataBuffer);
+    }
+
+    /**
+     * Gets the sample for the specified band of the specified
+     * pixel as a float.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the band.
+     * 
+     * @return the sample for the specified band of the specified
+     * pixel as a float.
+     */
+    public float getSampleFloat(int x, int y, int b) {
+        return sampleModel.getSampleFloat(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, b, dataBuffer);
+    }
+
+    /**
+     * Gets the SampleModel associated with this Raster.
+     * 
+     * @return the SampleModel associated with this Raster.
+     */
+    public SampleModel getSampleModel() {
+        return sampleModel;
+    }
+
+    /**
+     * Gets the translation of the X coordinate from the SampleModel
+     * coordinate system to the Rasters's coordinate system.
+     * 
+     * @return the value of the translation of the X coordinate from 
+     * the SampleModel coordinate system to the Rasters's 
+     * coordinate system.
+     */
+    public final int getSampleModelTranslateX() {
+        return sampleModelTranslateX;
+    }
+
+    /**
+     * Gets the translation of the Y coordinate from the SampleModel
+     * coordinate system to the Rasters's coordinate system.
+     * 
+     * @return the value of the translation of the Y coordinate from 
+     * the SampleModel coordinate system to the Rasters's 
+     * coordinate system.
+
+     */
+    public final int getSampleModelTranslateY() {
+        return sampleModelTranslateY;
+    }
+
+    /**
+     * Gets the double array of samples for the specified band 
+     * of the specified rectangular area of pixels in this Raster
+     * as a double array.
+     * 
+     * @param x the X coordinate of the rectangular area of pixels. 
+     * @param y the Y coordinate of the rectangular area of pixels.
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param b the band.
+     * @param dArray the resulting double array.
+     * 
+     * @return the double array of samples for the specified band 
+     * of the specified rectangular area of pixels.
+     */
+    public double[] getSamples(int x, int y, int w, int h, int b,
+            double dArray[]) {
+
+        return sampleModel.getSamples(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
+    }
+
+    /**
+     * Gets the float array of samples for the specified band 
+     * of the specified rectangular area of pixels in this Raster
+     * as a float array.
+     * 
+     * @param x the X coordinate of the rectangular area of pixels. 
+     * @param y the Y coordinate of the rectangular area of pixels.
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param b the band.
+     * @param fArray the resulting float array.
+     * 
+     * @return the float array of samples for the specified band 
+     * of the specified rectangular area of pixels.
+     */
+    public float[] getSamples(int x, int y, int w, int h, int b, float fArray[]) {
+
+        return sampleModel.getSamples(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
+    }
+
+    /**
+     * Gets the int array of samples for the specified band 
+     * of the specified rectangular area of pixels in this Raster
+     * as a int array.
+     * 
+     * @param x the X coordinate of the rectangular area of pixels. 
+     * @param y the Y coordinate of the rectangular area of pixels.
+     * @param w the width of the rectangular area of pixels.
+     * @param h the height of the rectangular area of pixels.
+     * @param b the band.
+     * @param iArray the resulting int array.
+     * 
+     * @return the int array of samples for the specified band 
+     * of the specified rectangular area of pixels.
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[]) {
+        return sampleModel.getSamples(x - sampleModelTranslateX, y
+                - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
+    }
+
+    /**
+     * Gets the transfer type for pixels of this Raster.
+     * @see SampleModel#getTransferType()
+     * 
+     * @return the transfer type for pixels of this Raster.
+     */
+    public final int getTransferType() {
+        return sampleModel.getTransferType();
+    }
+
+    /**
+     * Gets the width of this Raster.
+     * 
+     * @return the width of this Raster.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Validate data buffer.
+     * 
+     * @param dataBuffer the data buffer
+     * @param w the w
+     * @param h the h
+     * @param scanlineStride the scanline stride
+     */
+    private static void validateDataBuffer(final DataBuffer dataBuffer, final int w,
+            final int h, final int scanlineStride) {
+        if (dataBuffer.getSize() < (scanlineStride * (h - 1) + w - 1)) {
+            // awt.298=dataBuffer is too small
+            throw new RasterFormatException(Messages.getString("awt.298")); //$NON-NLS-1$
+        }
+    }
+}
+
+
diff --git a/awt/java/awt/image/RasterFormatException.java b/awt/java/awt/image/RasterFormatException.java
new file mode 100644
index 0000000..8577dad
--- /dev/null
+++ b/awt/java/awt/image/RasterFormatException.java
@@ -0,0 +1,45 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * The RasterFormatException class represents the exception 
+ * that is thrown when there's an invalid layout
+ * in the Raster.
+ */
+public class RasterFormatException extends RuntimeException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = 96598996116164315L;
+
+    /**
+     * Instantiates a new RasterFormatException with the 
+     * specified detail message.
+     * 
+     * @param s the detail message.
+     */
+    public RasterFormatException(String s) {
+        super(s);
+    }
+
+}
+
diff --git a/awt/java/awt/image/RasterOp.java b/awt/java/awt/image/RasterOp.java
new file mode 100644
index 0000000..e8933ee
--- /dev/null
+++ b/awt/java/awt/image/RasterOp.java
@@ -0,0 +1,83 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * The RasterOp interface provides methods for performing transformations
+ * from source data to destination data for Raster objects. The source and 
+ * destination objects should contain the appropriate number of bands for 
+ * the particular classes which implement this interface.
+ */
+public interface RasterOp {
+    
+    /**
+     * Creates a destination WritableRaster with the specified Raster;
+     * this destination image data is empty and has the correct size 
+     * and number of bands.   
+     * 
+     * @param src the source Raster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createCompatibleDestRaster(Raster src);
+
+    /**
+     * Performs a filter operation on the source Raster and stores the resulting
+     * image data to the destination WritableRaster.
+     * 
+     * @param src the source Raster.
+     * @param dst the destination WritableRaster, where the result is stored.
+     * 
+     * @return the filtered WritableRaster.
+     */
+    public WritableRaster filter(Raster src, WritableRaster dst);
+
+    /**
+     * Gets the bounds of the filtered Raster.
+     * 
+     * @param src the source Raster to be filtered.
+     * 
+     * @return the rectangle bounds of the filtered Raster.
+     */
+    public Rectangle2D getBounds2D(Raster src);
+
+    /**
+     * Gets the point of the destination image which corresponds
+     * to the specified point in the source raster.
+     * 
+     * @param srcPoint the point of the source raster.
+     * @param dstPoint the point where the result will be stored.
+     * 
+     * @return the destination point.
+     */
+    public Point2D getPoint2D(Point2D srcPoint, Point2D dstPoint);
+
+    /**
+     * Gets the RenderingHints of the RasterOp.
+     * 
+     * @return the RenderingHints of the RasterOp.
+     */
+    public RenderingHints getRenderingHints();
+}
diff --git a/awt/java/awt/image/RenderedImage.java b/awt/java/awt/image/RenderedImage.java
new file mode 100644
index 0000000..db3a4c8
--- /dev/null
+++ b/awt/java/awt/image/RenderedImage.java
@@ -0,0 +1,198 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Rectangle;
+import java.util.Vector;
+
+/**
+ * The RenderedImage interface should be implemented by all objects which 
+ * contains image data. The image data is represented as a single tile or 
+ * an array of tiles.
+ */
+public interface RenderedImage {
+
+    /**
+     * Gets the property with the specified name from the property set 
+     * of this RenderedImage.
+     * 
+     * @param name the property's name.
+     * 
+     * @return the property value corresponded to this property's name.
+     */
+    public Object getProperty(String name);
+
+    /**
+     * Copies the region of this RenderedImage to the specified 
+     * WritableRaster. The bounds of the region are the bounds of the 
+     * WritableRaster.
+     * 
+     * @param raster the WritableRaster.
+     * 
+     * @return the created WritableRaster.
+     */
+    public WritableRaster copyData(WritableRaster raster);
+
+    /**
+     * Gets the image data of the image's region as one tile.
+     * 
+     * @param rect the rectangular region of RenderedImage.
+     * 
+     * @return the image data of the image's region as one tile.
+     */
+    public Raster getData(Rectangle rect);
+
+    /**
+     * Gets all RenderedImage objects which are the source of this
+     * RenderedImage object.
+     * 
+     * @return a Vector of RenderedImage objects which are the source 
+     * of this RenderedImage object or null, if there is no information
+     * about them.
+     */
+    public Vector<RenderedImage> getSources();
+
+    /**
+     * Gets the set of all property names for this RenderedImage.
+     * 
+     * @return the array of all property names for this RenderedImage.
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Gets the SampleModel of this RenderedImage.
+     * 
+     * @return the SampleModel of this RenderedImage.
+     */
+    public SampleModel getSampleModel();
+
+    /**
+     * Gets the tile corresponded to the specified indices in the tile
+     * array.
+     * 
+     * @param tileX the X index of the tile.  
+     * @param tileY the Y index of the tile. 
+     * 
+     * @return the tile corresponded to the specified indices in the tile
+     * array.
+     */
+    public Raster getTile(int tileX, int tileY);
+
+    /**
+     * Gets the image data of this image as one tile.
+     * 
+     * @return the image data of this image as one tile.
+     */
+    public Raster getData();
+
+    /**
+     * Gets the ColorModel of this RenderedImage.
+     * 
+     * @return the ColorModel of this RenderedImage.
+     */
+    public ColorModel getColorModel();
+
+    /**
+     * Gets the width of the RenderedImage.
+     * 
+     * @return the width of the RenderedImage.
+     */
+    public int getWidth();
+
+    /**
+     * Gets the tile width.
+     * 
+     * @return the tile width in pixels.
+     */
+    public int getTileWidth();
+
+    /**
+     * Gets the tile height.
+     * 
+     * @return the tile height in pixels.
+     */
+    public int getTileHeight();
+
+    /**
+     * Gets the Y offset of the tile grid.
+     * 
+     * @return the Y offset of the tile grid.
+     */
+    public int getTileGridYOffset();
+
+    /**
+     * Gets the X offset of the tile grid.
+     * 
+     * @return the X offset of the tile grid.
+     */
+    public int getTileGridXOffset();
+
+    /**
+     * Gets the number of tiles along Y direction.
+     * 
+     * @return the number of tiles along Y direction.
+     */
+    public int getNumYTiles();
+
+    /**
+     * Gets the number of tiles along X direction.
+     * 
+     * @return the number of tiles along X direction.
+     */
+    public int getNumXTiles();
+
+    /**
+     * Gets the minimum Y coordinate of this RenderedImage.
+     * 
+     * @return the minimum Y coordinate of this RenderedImage.
+     */
+    public int getMinY();
+
+    /**
+     * Gets the minimum X coordinate of this RenderedImage.
+     * 
+     * @return the minimum X coordinate of this RenderedImage.
+     */
+    public int getMinX();
+
+    /**
+     * Gets the minimum tile's index along the Y direction.
+     * 
+     * @return the minimum tile's index along the Y direction.
+     */
+    public int getMinTileY();
+
+    /**
+     * Gets the minimum tile's index along the X direction.
+     * 
+     * @return the minimum tile's index along the X direction.
+     */
+    public int getMinTileX();
+
+    /**
+     * Gets the height of the RenderedImage.
+     * 
+     * @return the height of the RenderedImage.
+     */
+    public int getHeight();
+
+}
+
diff --git a/awt/java/awt/image/ReplicateScaleFilter.java b/awt/java/awt/image/ReplicateScaleFilter.java
new file mode 100644
index 0000000..9298125
--- /dev/null
+++ b/awt/java/awt/image/ReplicateScaleFilter.java
@@ -0,0 +1,213 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * The ReplicateScaleFilter class scales an source image 
+ * by replicating rows and columns of pixels to scale up or 
+ * omitting rows and columns of pixels to scale down.
+ */
+public class ReplicateScaleFilter extends ImageFilter {
+
+    /** The width of a source image. */
+    protected int srcWidth;
+
+    /** The height of a source image. */
+    protected int srcHeight;
+
+    /** The width of a destination image. */
+    protected int destWidth;
+
+    /** The height of a destination image. */
+    protected int destHeight;
+
+    /** The int array of source rows. */
+    protected int[] srcrows;
+
+    /** The int array of source columns. */
+    protected int[] srccols;
+
+    /** 
+     * An Object (byte array with a destination width) provides 
+     * a row of pixel data to the ImageConsumer. 
+     */
+    protected Object outpixbuf;
+
+    /**
+     * Instantiates a new ReplicateScaleFilter that filters 
+     * the image with the specified width and height.
+     * 
+     * @param width the width of scaled image.
+     * @param height the height of scaled image.
+     */
+    public ReplicateScaleFilter(int width, int height) {
+        if(width == 0 || height == 0) {
+            // awt.234=Width or Height equals zero
+            throw new IllegalArgumentException(Messages.getString("awt.234")); //$NON-NLS-1$
+        }
+
+        this.destWidth = width;
+        this.destHeight = height;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setProperties(Hashtable<?, ?> props) {
+        Hashtable<Object, Object> fprops;
+        if(props == null) {
+            fprops = new Hashtable<Object, Object>();
+        } else {
+            fprops = (Hashtable<Object, Object>) props.clone();
+        }
+        String propName = "Rescale Filters"; //$NON-NLS-1$
+        String prop = "destWidth=" + destWidth + "; " +  //$NON-NLS-1$ //$NON-NLS-2$
+        "destHeight=" + destHeight; //$NON-NLS-1$
+        Object o = fprops.get(propName);
+        if(o != null){
+            if(o instanceof String){
+                prop = (String)o + "; " + prop; //$NON-NLS-1$
+            }else{
+                prop =  o.toString() + "; " + prop; //$NON-NLS-1$
+            }
+        }
+        fprops.put(propName, prop);
+        consumer.setProperties(fprops);
+     }
+
+    // setPixels methods produce pixels according to Java API Spacification
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, 
+            ColorModel model, int[] pixels, int off, int scansize) {
+        
+        if(srccols == null) {
+            initArrays();
+        }
+        int buff[];
+        if(outpixbuf == null || !(outpixbuf instanceof int[])){
+            buff = new int[destWidth];
+            outpixbuf = buff;
+        }else{
+            buff = (int[])outpixbuf;
+        }
+
+        int wa = (srcWidth - 1) >>> 1;
+        int ha = (srcHeight - 1) >>> 1;
+        int dstX = (x * destWidth + wa) / srcWidth;
+        int dstY = (y * destHeight + ha) / srcHeight;
+
+        int sx, sy, dx, dy;
+        dy = dstY;
+        while((dy < destHeight) && ((sy = srcrows[dy]) < y + h)){
+            dx = dstX;
+            int srcOff = off + (sy - y) * scansize;
+            while((dx < destWidth) && ((sx = srccols[dx]) < x + w)){
+                buff[dx] = pixels[srcOff + (sx - x)];
+                dx++;
+            }
+
+            consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, 
+                    dstX, destWidth);
+            dy++;
+        }
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, 
+            ColorModel model, byte[] pixels, int off, int scansize) {
+        
+        if(srccols == null) {
+            initArrays();
+        }
+        byte buff[];
+        if(outpixbuf == null || !(outpixbuf instanceof byte[])){
+            buff = new byte[destWidth];
+            outpixbuf = buff;
+        }else{
+            buff = (byte[])outpixbuf;
+        }
+
+        int wa = (srcWidth - 1) >>> 1;
+        int ha = (srcHeight - 1) >>> 1;
+        int dstX = (x * destWidth + wa) / srcWidth;
+        int dstY = (y * destHeight + ha) / srcHeight;
+
+        int sx, sy, dx, dy;
+        dy = dstY;
+        while((dy < destHeight) && ((sy = srcrows[dy]) < y + h)){
+            dx = dstX;
+            int srcOff = off + (sy - y) * scansize;
+            while((dx < destWidth) && ((sx = srccols[dx]) < x + w)){
+                buff[dx] = pixels[srcOff + (sx - x)];
+                dx++;
+            }
+
+            consumer.setPixels(dstX, dy, dx - dstX, 1, model, buff, 
+                    dstX, destWidth);
+            dy++;
+        }
+    }
+
+    @Override
+    public void setDimensions(int w, int h) {
+        srcWidth = w;
+        srcHeight = h;
+
+        if(destWidth < 0 && destHeight < 0){
+            destWidth = srcWidth;
+            destHeight = srcHeight;
+        }else if(destWidth < 0){
+            destWidth = destHeight * srcWidth / srcHeight;
+        }else if(destHeight < 0){
+            destHeight = destWidth * srcHeight / srcWidth;
+        }
+        consumer.setDimensions(destWidth, destHeight);
+    }
+
+    /**
+     * Initialization of srccols and srcrows arrays.
+     */
+    private void initArrays(){
+        if ((destWidth < 0) || (destHeight < 0)) {
+            throw new IndexOutOfBoundsException();
+        }
+        
+        srccols = new int[destWidth];
+        int ca = srcWidth >>> 1;
+        for(int i = 0; i < destWidth; i++){
+            srccols[i] = (i * srcWidth + ca) / destWidth;
+        }
+
+        srcrows = new int[destHeight];
+        int ra = srcHeight >>> 1;
+        for(int i = 0; i < destHeight; i++){
+            srcrows[i] = (i * srcHeight + ra) / destHeight;
+        }
+    }
+
+}
+
+
diff --git a/awt/java/awt/image/RescaleOp.java b/awt/java/awt/image/RescaleOp.java
new file mode 100644
index 0000000..0e96031
--- /dev/null
+++ b/awt/java/awt/image/RescaleOp.java
@@ -0,0 +1,659 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 6, 2005
+ */
+
+package java.awt.image;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.*;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RescaleOp performs rescaling of the source image data
+ * by multiplying the pixel values with a scale factor 
+ * and then adding an offset.
+ */
+public class RescaleOp implements BufferedImageOp, RasterOp {
+    
+    /** The scale factors. */
+    private float scaleFactors[];
+    
+    /** The offsets. */
+    private float offsets[];
+    
+    /** The hints. */
+    private RenderingHints hints;
+
+    static {
+        // TODO
+        //System.loadLibrary("imageops");
+    }
+
+    /**
+     * Instantiates a new RescaleOp object with the specified 
+     * scale factors and offsets.
+     * 
+     * @param scaleFactors the array of scale factor values.
+     * @param offsets the array of offset values.
+     * @param hints the RenderingHints or null.
+     */
+    public RescaleOp(float[] scaleFactors, float[] offsets, RenderingHints hints) {
+        int numFactors = Math.min(scaleFactors.length, offsets.length);
+
+        this.scaleFactors = new float[numFactors];
+        this.offsets = new float[numFactors];
+
+        System.arraycopy(scaleFactors, 0, this.scaleFactors, 0, numFactors);
+        System.arraycopy(offsets, 0, this.offsets, 0, numFactors);
+
+        this.hints = hints;
+    }
+
+    /**
+     * Instantiates a new RescaleOp object with the specified 
+     * scale factor and offset.
+     * 
+     * @param scaleFactor the scale factor.
+     * @param offset the offset.
+     * @param hints the RenderingHints or null.
+     */
+    public RescaleOp(float scaleFactor, float offset, RenderingHints hints) {
+        scaleFactors = new float[1];
+        offsets = new float[1];
+
+        scaleFactors[0] = scaleFactor;
+        offsets[0] = offset;
+
+        this.hints = hints;
+    }
+
+    /**
+     * Gets the number of scaling factors.
+     * 
+     * @return the number of scaling factors.
+     */
+    public final int getNumFactors() {
+        return scaleFactors.length;
+    }
+
+    public final RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    /**
+     * Gets the scale factors of this RescaleOp.
+     * 
+     * @param scaleFactors the desired scale factors array will be copied 
+     * to this array.
+     * 
+     * @return the scale factors array.
+     */
+    public final float[] getScaleFactors(float[] scaleFactors) {
+        if (scaleFactors == null) {
+            scaleFactors = new float[this.scaleFactors.length];
+        }
+
+        int minLength = Math.min(scaleFactors.length, this.scaleFactors.length);
+        System.arraycopy(this.scaleFactors, 0, scaleFactors, 0, minLength);
+        return scaleFactors;
+    }
+
+    /**
+     * Gets the offsets array of this RescaleOp.
+     * 
+     * @param offsets the desired offsets array will be copied to this array.
+     * 
+     * @return the offsets array of this RescaleOp.
+     */
+    public final float[] getOffsets(float[] offsets) {
+        if (offsets == null) {
+            offsets = new float[this.offsets.length];
+        }
+
+        int minLength = Math.min(offsets.length, this.offsets.length);
+        System.arraycopy(this.offsets, 0, offsets, 0, minLength);
+        return offsets;
+    }
+
+    public final Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
+        if (dstPt == null) {
+            dstPt = new Point2D.Float();
+        }
+
+        dstPt.setLocation(srcPt);
+        return dstPt;
+    }
+
+    public final Rectangle2D getBounds2D(Raster src) {
+        return src.getBounds();
+    }
+
+    public final Rectangle2D getBounds2D(BufferedImage src) {
+        return getBounds2D(src.getRaster());
+    }
+
+    public WritableRaster createCompatibleDestRaster(Raster src) {
+        return src.createCompatibleWritableRaster();
+    }
+
+    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
+        if (dstCM == null) {
+            dstCM = src.getColorModel();
+        }
+
+        if (dstCM instanceof IndexColorModel) {
+            dstCM = ColorModel.getRGBdefault();
+        }
+
+        WritableRaster r =
+                dstCM.isCompatibleSampleModel(src.getSampleModel()) ?
+                src.getRaster().createCompatibleWritableRaster(src.getWidth(), src.getHeight()) :
+                dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight());
+
+        return new BufferedImage(
+                dstCM,
+                r,
+                dstCM.isAlphaPremultiplied(),
+                null
+        );
+    }
+
+    public final WritableRaster filter(Raster src, WritableRaster dst) {
+        if (dst == null) {
+            dst = createCompatibleDestRaster(src);
+        } else {
+            if (src.getNumBands() != dst.getNumBands()) {
+                // awt.21D=Number of src bands ({0}) does not match number of dst bands ({1})
+                throw new IllegalArgumentException(Messages.getString("awt.21D", //$NON-NLS-1$
+                        src.getNumBands(), dst.getNumBands()));
+            }
+        }
+
+        if (
+                this.scaleFactors.length != 1 &&
+                this.scaleFactors.length != src.getNumBands()
+        ) {
+            // awt.21E=Number of scaling constants is not equal to the number of bands
+            throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+        }
+
+        // TODO
+        //if (ippFilter(src, dst, BufferedImage.TYPE_CUSTOM, false) != 0)
+            if (slowFilter(src, dst, false) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        return dst;
+    }
+
+    /**
+     * Slow filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    private final int slowFilter(Raster src, WritableRaster dst, boolean skipAlpha) {
+        SampleModel sm = src.getSampleModel();
+
+        int numBands = src.getNumBands();
+        int srcHeight = src.getHeight();
+        int srcWidth = src.getWidth();
+
+        int srcMinX = src.getMinX();
+        int srcMinY = src.getMinY();
+        int dstMinX = dst.getMinX();
+        int dstMinY = dst.getMinY();
+
+        int[] maxValues = new int[numBands];
+        int[] masks = new int[numBands];
+        int[] sampleSizes = sm.getSampleSize();
+
+        for (int i=0; i < numBands; i++){
+            maxValues[i] = (1 << sampleSizes[i]) - 1;
+            masks[i] = ~(maxValues[i]);
+        }
+
+        // Processing bounds
+        float[] pixels = null;
+        pixels = src.getPixels(srcMinX, srcMinY, srcWidth, srcHeight, pixels);
+
+        // Cycle over pixels to be calculated
+        if (skipAlpha) { // Always suppose that alpha channel is the last band
+            if (scaleFactors.length > 1) {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands-1; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[bandIdx] + offsets[bandIdx];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+
+                    i++;
+                }
+            } else {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands-1; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[0] + offsets[0];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+
+                    i++;
+                }
+            }
+        } else {
+            if (scaleFactors.length > 1) {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[bandIdx] + offsets[bandIdx];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+                }
+            } else {
+                for (int i = 0; i < pixels.length; ){
+                    for (int bandIdx = 0; bandIdx < numBands; bandIdx++, i++){
+                        pixels[i] = pixels[i] * scaleFactors[0] + offsets[0];
+                        // Check for overflow now
+                        if (((int)pixels[i] & masks[bandIdx]) != 0) {
+                            if (pixels[i] < 0) {
+                                pixels[i] = 0;
+                            } else {
+                                pixels[i] = maxValues[bandIdx];
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        dst.setPixels(dstMinX, dstMinY, srcWidth, srcHeight, pixels);
+
+        return 0;
+    }
+
+    public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
+        ColorModel srcCM = src.getColorModel();
+
+        if (srcCM instanceof IndexColorModel) {
+            // awt.220=Source should not have IndexColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.220")); //$NON-NLS-1$
+        }
+
+        // Check if the number of scaling factors matches the number of bands
+        int nComponents = srcCM.getNumComponents();
+        boolean skipAlpha;
+        if (srcCM.hasAlpha()) {
+            if (scaleFactors.length == 1 || scaleFactors.length == nComponents-1) {
+                skipAlpha = true;
+            } else if (scaleFactors.length == nComponents) {
+                skipAlpha = false;
+            } else {
+                // awt.21E=Number of scaling constants is not equal to the number of bands
+                throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+            }
+        } else if (scaleFactors.length == 1 || scaleFactors.length == nComponents) {
+            skipAlpha = false;
+        } else {
+            // awt.21E=Number of scaling constants is not equal to the number of bands
+            throw new IllegalArgumentException(Messages.getString("awt.21E")); //$NON-NLS-1$
+        }
+
+        BufferedImage finalDst = null;
+        if (dst == null) {
+            finalDst = dst;
+            dst = createCompatibleDestImage(src, srcCM);
+        } else if (!srcCM.equals(dst.getColorModel())) {
+            // Treat BufferedImage.TYPE_INT_RGB and BufferedImage.TYPE_INT_ARGB as same
+            if (
+                    !((src.getType() == BufferedImage.TYPE_INT_RGB ||
+                       src.getType() == BufferedImage.TYPE_INT_ARGB) &&
+                      (dst.getType() == BufferedImage.TYPE_INT_RGB ||
+                       dst.getType() == BufferedImage.TYPE_INT_ARGB))
+            ) {
+                finalDst = dst;
+                dst = createCompatibleDestImage(src, srcCM);
+            }
+        }
+
+        // TODO
+        //if (ippFilter(src.getRaster(), dst.getRaster(), src.getType(), skipAlpha) != 0)
+            if (slowFilter(src.getRaster(), dst.getRaster(), skipAlpha) != 0) {
+                // awt.21F=Unable to transform source
+                throw new ImagingOpException (Messages.getString("awt.21F")); //$NON-NLS-1$
+            }
+
+        if (finalDst != null) {
+            Graphics2D g = finalDst.createGraphics();
+            g.setComposite(AlphaComposite.Src);
+            g.drawImage(dst, 0, 0, null);
+        } else {
+            finalDst = dst;
+        }
+
+        return finalDst;
+    }
+
+    // Don't forget to pass allocated arrays for levels and values, size should be numBands*4
+    /**
+     * Creates the levels.
+     * 
+     * @param sm the sm
+     * @param numBands the num bands
+     * @param skipAlpha the skip alpha
+     * @param levels the levels
+     * @param values the values
+     * @param channelsOrder the channels order
+     */
+    private final void createLevels(
+            SampleModel sm, int numBands, boolean skipAlpha,
+            int levels[], int values[], int channelsOrder[]
+    ) {
+        // Suppose same sample size for all channels, otherwise use slow filter
+        int maxValue = (1 << sm.getSampleSize(0)) - 1;
+
+        // For simplicity introduce these arrays
+        float extScaleFactors[] = new float[numBands];
+        float extOffsets[] = new float[numBands];
+
+        if (scaleFactors.length != 1) {
+            System.arraycopy(scaleFactors, 0, extScaleFactors, 0, scaleFactors.length);
+            System.arraycopy(offsets, 0, extOffsets, 0, scaleFactors.length);
+        } else {
+            for (int i = 0; i < numBands; i++) {
+                extScaleFactors[i] = scaleFactors[0];
+                extOffsets[i] = offsets[0];
+            }
+        }
+
+        if (skipAlpha) {
+            extScaleFactors[numBands-1] = 1;
+            extOffsets[numBands-1] = 0;
+        }
+
+        // Create a levels
+        for (int i=0; i<numBands; i++) {
+            if (extScaleFactors[i] == 0) {
+                levels[i*4] = 0;
+                levels[i*4+1] = 0;
+                levels[i*4+2] = maxValue+1;
+                levels[i*4+3] = maxValue+1;
+            }
+
+            float minLevel = -extOffsets[i] / extScaleFactors[i];
+            float maxLevel = (maxValue - extOffsets[i]) / extScaleFactors[i];
+
+            if (minLevel < 0) {
+                minLevel = 0;
+            } else if (minLevel > maxValue){
+                minLevel = maxValue;
+            }
+
+            if (maxLevel < 0) {
+                maxLevel = 0;
+            } else if (maxLevel > maxValue){
+                maxLevel = maxValue;
+            }
+
+            levels[i*4] = 0;
+            if (minLevel > maxLevel) {
+                levels[i*4+1] = (int) maxLevel;
+                levels[i*4+2] = (int) minLevel;
+            } else {
+                levels[i*4+1] = (int) minLevel;
+                levels[i*4+2] = (int) maxLevel;
+            }
+            levels[i*4+3] = maxValue+1;
+
+            // Fill values
+            for (int k=0; k<4; k++) {
+                int idx = i*4+k;
+                values[idx] = (int) (extScaleFactors[i] * levels[idx] + extOffsets[i]);
+                if (values[idx] < 0) {
+                    values[idx] = 0;
+                } else if (values[idx] > maxValue){
+                    values[idx] = maxValue;
+                }
+            }
+        }
+
+        // Reorder data if channels are stored in different order
+        if (channelsOrder != null) {
+            int len = numBands*4;
+            int savedLevels[] = new int[len];
+            int savedValues[] = new int[len];
+            System.arraycopy(levels, 0, savedLevels, 0, len);
+            System.arraycopy(values, 0, savedValues, 0, len);
+            for (int i = 0; i < channelsOrder.length; i++) {
+                System.arraycopy(savedLevels, i*4, levels, channelsOrder[i]*4, 4);
+                System.arraycopy(savedValues, i*4, values, channelsOrder[i]*4, 4);
+            }
+        }
+    }
+
+    // TODO remove when this method is used
+    /**
+     * Ipp filter.
+     * 
+     * @param src the src
+     * @param dst the dst
+     * @param imageType the image type
+     * @param skipAlpha the skip alpha
+     * 
+     * @return the int
+     */
+    @SuppressWarnings("unused")
+    private final int ippFilter(
+            Raster src, WritableRaster dst,
+            int imageType, boolean skipAlpha
+    ) {
+        int res;
+
+        int srcStride, dstStride;
+        int channels;
+        int offsets[] = null;
+        int channelsOrder[] = null;
+
+        switch (imageType) {
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE:
+            case BufferedImage.TYPE_INT_RGB: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                channelsOrder = new int[] {2, 1, 0, 3};
+                break;
+            }
+
+            case BufferedImage.TYPE_4BYTE_ABGR:
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+            case BufferedImage.TYPE_INT_BGR: {
+                channels = 4;
+                srcStride = src.getWidth()*4;
+                dstStride = dst.getWidth()*4;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                channels = 1;
+                srcStride = src.getWidth();
+                dstStride = dst.getWidth();
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                channels = 3;
+                srcStride = src.getWidth()*3;
+                dstStride = dst.getWidth()*3;
+                channelsOrder = new int[] {2, 1, 0};
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY:
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_BINARY: {
+                return slowFilter(src, dst, skipAlpha);
+            }
+
+            default: {
+                SampleModel srcSM = src.getSampleModel();
+                SampleModel dstSM = dst.getSampleModel();
+
+                if (
+                        srcSM instanceof PixelInterleavedSampleModel &&
+                        dstSM instanceof PixelInterleavedSampleModel
+                ) {
+                    // Check PixelInterleavedSampleModel
+                    if (
+                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
+                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    channels = srcSM.getNumBands(); // Have IPP functions for 1, 3 and 4 channels
+                    if (!(channels == 1 || channels == 3 || channels == 4)) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride();
+                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride();
+
+                    channelsOrder = ((ComponentSampleModel) srcSM).getBandOffsets();
+                } else if (
+                        srcSM instanceof SinglePixelPackedSampleModel &&
+                        dstSM instanceof SinglePixelPackedSampleModel
+                ) {
+                    // Check SinglePixelPackedSampleModel
+                    SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
+                    SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;
+
+                    channels = sppsm1.getNumBands();
+
+                     // TYPE_INT_RGB, TYPE_INT_ARGB...
+                    if (
+                            sppsm1.getDataType() != DataBuffer.TYPE_INT ||
+                            sppsm2.getDataType() != DataBuffer.TYPE_INT ||
+                            !(channels == 3 || channels == 4)
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    // Check compatibility of sample models
+                    if (
+                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
+                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
+                    ) {
+                        return slowFilter(src, dst, skipAlpha);
+                    }
+
+                    for (int i=0; i<channels; i++) {
+                        if (sppsm1.getSampleSize(i) != 8) {
+                            return slowFilter(src, dst, skipAlpha);
+                        }
+                    }
+
+                    channelsOrder = new int[channels];
+                    int bitOffsets[] = sppsm1.getBitOffsets();
+                    for (int i=0; i<channels; i++) {
+                        channelsOrder[i] = bitOffsets[i] / 8;
+                    }
+
+                    if (channels == 3) { // Don't skip channel now, could be optimized
+                        channels = 4;
+                    }
+
+                    srcStride = sppsm1.getScanlineStride() * 4;
+                    dstStride = sppsm2.getScanlineStride() * 4;
+                } else {
+                    return slowFilter(src, dst, skipAlpha);
+                }
+
+                // Fill offsets if there's a child raster
+                if (src.getParent() != null || dst.getParent() != null) {
+                    if (
+                            src.getSampleModelTranslateX() != 0 ||
+                            src.getSampleModelTranslateY() != 0 ||
+                            dst.getSampleModelTranslateX() != 0 ||
+                            dst.getSampleModelTranslateY() != 0
+                    ) {
+                        offsets = new int[4];
+                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
+                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
+                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
+                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
+                    }
+                }
+            }
+        }
+
+        int levels[] = new int[4*channels];
+        int values[] = new int[4*channels];
+
+        createLevels(src.getSampleModel(), channels, skipAlpha, levels, values, channelsOrder);
+
+        Object srcData, dstData;
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            srcData = dbAccess.getData(src.getDataBuffer());
+            dstData = dbAccess.getData(dst.getDataBuffer());
+        } catch (IllegalArgumentException e) {
+            return -1; // Unknown data buffer type
+        }
+
+        res = LookupOp.ippLUT(
+            srcData, src.getWidth(), src.getHeight(), srcStride,
+            dstData, dst.getWidth(), dst.getHeight(), dstStride,
+            levels, values,
+            channels, offsets,
+            true
+        );
+
+        return res;
+    }
+}
diff --git a/awt/java/awt/image/SampleModel.java b/awt/java/awt/image/SampleModel.java
new file mode 100644
index 0000000..44059a0
--- /dev/null
+++ b/awt/java/awt/image/SampleModel.java
@@ -0,0 +1,1053 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The SampleModel class is abstract class for retrieving pixel's samples
+ * in the data of an image. Each pixel contains several samples. A 
+ * sample is the set of values of the bands for single pixel. 
+ * For example, each pixel in the RGB model contains three samples 
+ * and there are three corresponding bands in the image 
+ * data of such pixels representing red, green and blue components.
+ * <p> 
+ * The image data is represented as a Raster with a DataBuffer 
+ * and a SampleModel. The SampleModel allows access to the samples in the 
+ * DataBuffer. 
+ */
+public abstract class SampleModel {
+
+    /** The width of the image data which this SampleModel describes. */
+    protected int width;
+
+    /** The height of the image data which this SampleModel describes. */
+    protected int height;
+
+    /** The number of bands of image data which this SampleModel describes. */
+    protected int numBands;
+
+    /** The data type of the image data which this SampleModel describes. */
+    protected int dataType;
+
+    /**
+     * Instantiates a new SampleModel with the specified data type,
+     * width, height and number of bands.
+     * 
+     * @param dataType the data type of the image data.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param numBands the number of bands of the image data.
+     */
+    public SampleModel(int dataType, int w, int h, int numBands) {
+        if (w <= 0 || h <= 0) {
+            // awt.22E=w or h is less than or equal to zero
+            throw new IllegalArgumentException(Messages.getString("awt.22E")); //$NON-NLS-1$
+        }
+
+        double squre = ((double) w) * ((double) h);
+        if (squre >= Integer.MAX_VALUE) {
+            // awt.22F=The product of w and h is greater than Integer.MAX_VALUE
+            throw new IllegalArgumentException(Messages.getString("awt.22F")); //$NON-NLS-1$
+        }
+
+        if (dataType < DataBuffer.TYPE_BYTE ||
+                dataType > DataBuffer.TYPE_DOUBLE &&
+                dataType != DataBuffer.TYPE_UNDEFINED) {
+            // awt.230=dataType is not one of the supported data types
+            throw new IllegalArgumentException(Messages.getString("awt.230")); //$NON-NLS-1$
+        }
+
+        if (numBands < 1) {
+            // awt.231=Number of bands must be more then 0
+            throw new IllegalArgumentException(Messages.getString("awt.231")); //$NON-NLS-1$
+        }
+
+        this.dataType = dataType;
+        this.width = w;
+        this.height = h;
+        this.numBands = numBands;
+
+    }
+
+    /**
+     * Gets the data array for the specified pixel of the specified 
+     * DataBuffer with one of the following types: 
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param obj the Object is a data where the result will be stored.
+     * @param data the image data.
+     * 
+     * @return the data array for the specified pixel of the specified 
+     * DataBuffer.
+     */
+    public abstract Object getDataElements(int x, int y, Object obj,
+            DataBuffer data);
+
+    /**
+     * Gets the array of pixel data for the specified rectangular 
+     * area of pixels of the specified DataBuffer with one of 
+     * the following types: 
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * 
+     * @param x the X coordinate of the rectangular pixel area.
+     * @param y the Y coordinate of the rectangular pixel area.
+     * @param w the width of the rectangular pixel area.
+     * @param h the height of the rectangular pixel area.
+     * @param obj the Object is an array with the primitive type,
+     * where the result array will be stored.
+     * @param data the image data.
+     * 
+     * @return the array of pixel data for the specified rectangular 
+     * area of pixels of the specified DataBuffer object.
+     */
+    public Object getDataElements(int x, int y, int w, int h, Object obj,
+            DataBuffer data) {
+        int numDataElements = getNumDataElements();
+        int idx = 0;
+
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            byte bbuf[] = null;
+
+            if (obj == null) {
+                bdata = new byte[numDataElements * w * h];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    bbuf = (byte[]) getDataElements(j, i, bbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        bdata[idx++] = bbuf[n];
+                    }
+                }
+            }
+            obj = bdata;
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            short sbuf[] = null;
+
+            if (obj == null) {
+                sdata = new short[numDataElements * w * h];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    sbuf = (short[]) getDataElements(j, i, sbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        sdata[idx++] = sbuf[n];
+                    }
+                }
+            }
+            obj = sdata;
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            int ibuf[] = null;
+
+            if (obj == null) {
+                idata = new int[numDataElements * w * h];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    ibuf = (int[]) getDataElements(j, i, ibuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        idata[idx++] = ibuf[n];
+                    }
+                }
+            }
+            obj = idata;
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fdata[];
+            float fbuf[] = null;
+
+            if (obj == null) {
+                fdata = new float[numDataElements * w * h];
+            } else {
+                fdata = (float[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    fbuf = (float[]) getDataElements(j, i, fbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        fdata[idx++] = fbuf[n];
+                    }
+                }
+            }
+            obj = fdata;
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double ddata[];
+            double dbuf[] = null;
+
+            if (obj == null) {
+                ddata = new double[numDataElements * w * h];
+            } else {
+                ddata = (double[]) obj;
+            }
+
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    dbuf = (double[]) getDataElements(j, i, dbuf, data);
+                    for (int n = 0; n < numDataElements; n++) {
+                        ddata[idx++] = dbuf[n];
+                    }
+                }
+            }
+            obj = ddata;
+            break;
+
+        }
+
+        return obj;
+    }
+
+    /**
+     * Sets the data for a single pixel in the specified DataBuffer
+     * from a primitive array with one of the following types: 
+     * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param obj the Object - the array of primitive pixel data
+     * to be set. 
+     * @param data the image data.
+     */
+    public abstract void setDataElements(int x, int y, Object obj,
+            DataBuffer data);
+
+    /**
+     * Sets the data elements for a rectangular area of pixels in 
+     * the specified DataBuffer from a primitive array with one of 
+     * the following types: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. 
+     * 
+     * @param x the X coordinate of the specified rectangular area.
+     * @param y the Y coordinate of the specified rectangular area.
+     * @param w the width of rectangle.
+     * @param h the height of rectangle.
+     * @param obj the Object - the array of primitive pixel data
+     * to be set. 
+     * @param data the image data.
+     */
+    public void setDataElements(int x, int y, int w, int h, Object obj,
+            DataBuffer data) {
+        int numDataElements = getNumDataElements();
+        int idx = 0;
+
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bbuf[] = new byte[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        bbuf[n] = ((byte[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, bbuf, data);
+                }
+            }
+
+            break;
+
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+            short sbuf[] = new short[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        sbuf[n] = ((short[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, sbuf, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_INT:
+            int ibuf[] = new int[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        ibuf[n] = ((int[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, ibuf, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fbuf[] = new float[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        fbuf[n] = ((float[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, fbuf, data);
+                }
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double dbuf[] = new double[numDataElements];
+            for (int i = y; i < y + h; i++) {
+                for (int j = x; j < x + w; j++) {
+                    for (int n = 0; n < numDataElements; n++) {
+                        dbuf[n] = ((double[]) obj)[idx++];
+                    }
+                    setDataElements(j, i, dbuf, data);
+                }
+            }
+            break;
+
+        }
+    }
+
+    /**
+     * Creates a new SampleModel with the specified bands of 
+     * this SampleModel.
+     * 
+     * @param bands the array of bands from this SampleModel.
+     * 
+     * @return the SampleModel with the specified bands of 
+     * this SampleModel.
+     */
+    public abstract SampleModel createSubsetSampleModel(int bands[]);
+
+    /**
+     * Creates the SampleModel which has the same data as in 
+     * this SampleModel with a different width and height.
+     * 
+     * @param a0 the width of the image data.
+     * @param a1 the height of the image data.
+     * 
+     * @return the SampleModel which has the same data as in 
+     * this SampleModel with a different width and height.
+     */
+    public abstract SampleModel createCompatibleSampleModel(int a0, int a1);
+
+    /**
+     * Gets the samples of the specified pixel as a int array.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param iArray the int array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the int array with the samples of the specified pixel.
+
+     */
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+
+        if (iArray == null) {
+            pixel = new int[numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a int array of samples. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param iArray the int array.
+     * @param data the image data.
+     */
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the samples of the specified pixel as a float array.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param fArray the float array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the float array with the samples of the specified pixel.
+     */
+    public float[] getPixel(int x, int y, float fArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        float pixel[];
+
+        if (fArray == null) {
+            pixel = new float[numBands];
+        } else {
+            pixel = fArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSampleFloat(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a float array of samples. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param fArray the float array.
+     * @param data the image data.
+     */
+    public void setPixel(int x, int y, float fArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, fArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the samples of the specified pixel as a double array.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param dArray the double array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the double array with the samples of the specified pixel.
+     */
+    public double[] getPixel(int x, int y, double dArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        double pixel[];
+
+        if (dArray == null) {
+            pixel = new double[numBands];
+        } else {
+            pixel = dArray;
+        }
+
+        for (int i = 0; i < numBands; i++) {
+            pixel[i] = getSampleDouble(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    /**
+     * Sets a pixel of the DataBuffer from a double array of samples. 
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param dArray the double array.
+     * @param data the image data.
+     */
+    public void setPixel(int x, int y, double dArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < numBands; i++) {
+            setSample(x, y, i, dArray[i], data);
+        }
+    }
+
+    /**
+     * Gets the sample of a specified band for the specified pixel
+     * as an int.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param b the specified band.
+     * @param data the image data.
+     * 
+     * @return the sample of a specified band for the specified pixel.
+     */
+    public abstract int getSample(int x, int y, int b, DataBuffer data);
+
+    /**
+     * Gets the sample of a specified band for the specified pixel
+     * as a float.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param b the specified band.
+     * @param data the image data.
+     * 
+     * @return the sample of a specified band for the specified pixel.
+
+     */
+    public float getSampleFloat(int x, int y, int b, DataBuffer data) {
+        return getSample(x, y, b, data);
+    }
+
+    /**
+     * Gets the sample of a specified band for the specified pixel
+     * as a double.
+     * 
+     * @param x the X coordinate of pixel.
+     * @param y the Y coordinate of pixel.
+     * @param b the specified band.
+     * @param data the image data.
+     * 
+     * @return the sample of a specified band for the specified pixel.
+     */
+    public double getSampleDouble(int x, int y, int b, DataBuffer data) {
+        return getSample(x, y, b, data);
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels
+     * as a int array.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param iArray the int array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the int array with the samples of the specified 
+     * rectangular area of pixels.
+     */
+    public int[] getPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixels[];
+        int idx = 0;
+
+        if (iArray == null) {
+            pixels = new int[w * h * numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the DataBuffer
+     * from an int array. 
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param iArray the int array.
+     * @param data the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels 
+     * as a float array.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param fArray the float array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the float array with the samples of the specified 
+     * rectangular area of pixels.
+     */
+    public float[] getPixels(int x, int y, int w, int h, float fArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        float pixels[];
+        int idx = 0;
+
+        if (fArray == null) {
+            pixels = new float[w * h * numBands];
+        } else {
+            pixels = fArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSampleFloat(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the DataBuffer
+     * from a float array. 
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param fArray the float array.
+     * @param data the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, float fArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, fArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of the specified rectangular area of pixels 
+     * as a double array.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param dArray the double array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the double array with the samples of the specified 
+     * rectangular area of pixels.
+     */
+    public double[] getPixels(int x, int y, int w, int h, double dArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        double pixels[];
+        int idx = 0;
+
+        if (dArray == null) {
+            pixels = new double[w * h * numBands];
+        } else {
+            pixels = dArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    pixels[idx++] = getSampleDouble(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    /**
+     * Sets all of the samples for a rectangular area of pixels of the DataBuffer
+     * from a double array. 
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param dArray the double array.
+     * @param data the image data.
+     */
+    public void setPixels(int x, int y, int w, int h, double dArray[],
+            DataBuffer data) {
+        if (x < 0 || y < 0 || x + w > this.width || y + h > this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < numBands; n++) {
+                    setSample(j, i, n, dArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel
+     * in the DataBuffer as int value.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample as an int value.
+     * @param data the image data.
+     */
+    public abstract void setSample(int x, int y, int b, int s, DataBuffer data);
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular
+     * area of pixels as a int array.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param iArray the int array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the samples of a specified band for a specified rectangular
+     * area of pixels.
+     */
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an int array in the specified band for 
+     * the specified rectangle of pixels.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param iArray the int array.
+     * @param data the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular
+     * area of pixels as a float array.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param fArray the float array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the samples of a specified band for a specified rectangular
+     * area of pixels.
+     */
+    public float[] getSamples(int x, int y, int w, int h, int b,
+            float fArray[], DataBuffer data) {
+        float samples[];
+        int idx = 0;
+
+        if (fArray == null) {
+            samples = new float[w * h];
+        } else {
+            samples = fArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSampleFloat(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an float array in the specified band for 
+     * the specified rectangle of pixels.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param fArray the float array
+     * @param data the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, float fArray[],
+            DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, fArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Gets the samples of a specified band for a specified rectangular
+     * area of pixels as a double array.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param dArray the double array where result will be stored.
+     * @param data the image data.
+     * 
+     * @return the samples of a specified band for a specified rectangular
+     * area of pixels.
+     */
+    public double[] getSamples(int x, int y, int w, int h, int b,
+            double dArray[], DataBuffer data) {
+        double samples[];
+        int idx = 0;
+
+        if (dArray == null) {
+            samples = new double[w * h];
+        } else {
+            samples = dArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSampleDouble(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    /**
+     * Sets the samples from an double array in the specified band for 
+     * the specified rectangle of pixels.
+     * 
+     * @param x the X coordinate of the rectangle.
+     * @param y the Y coordinate of the rectangle.
+     * @param w the width of the rectangle.
+     * @param h the height of the rectangle.
+     * @param b the specified band.
+     * @param dArray the double array
+     * @param data the image data.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, double dArray[],
+            DataBuffer data) {
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(j, i, b, dArray[idx++], data);
+            }
+        }
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel
+     * in the DataBuffer as float value.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample as float value.
+     * @param data the image data.
+     */
+    public void setSample(int x, int y, int b, float s, DataBuffer data) {
+        setSample(x, y, b, (int) s, data);
+    }
+
+    /**
+     * Sets a sample of the specified band for the specified pixel
+     * in the DataBuffer as double value.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample as double value.
+     * @param data the image data.
+     */
+    public void setSample(int x, int y, int b, double s, DataBuffer data) {
+        setSample(x, y, b, (int) s, data);
+    }
+
+    /**
+     * Creates a DataBuffer object which corresponds to the SampleModel. 
+     *  
+     * @return the DataBuffer object which corresponds to 
+     * the SampleModel.
+     */
+    public abstract DataBuffer createDataBuffer();
+
+    /**
+     * Gets the sample size in bits for the specified band.
+     * 
+     * @param band the specified band.
+     * 
+     * @return the sample size in bits for the specified band.
+     */
+    public abstract int getSampleSize(int band);
+
+    /**
+     * Gets an array of the sample size in bits for all bands.
+     *  
+     * @return an array of the sample size in bits for all bands.
+     */
+    public abstract int[] getSampleSize();
+
+    /**
+     * Gets the width of the image data of this SampleModel object.
+     * 
+     * @return the width of the image data of this SampleModel object.
+     */
+    public final int getWidth() {
+        return width;
+    }
+
+    /**
+     * Gets the transfer type used to transfer pixels via 
+     * the getDataElements and setDataElements methods.
+     * Transfer type value can be one of the predefined type 
+     * from DataBuffer class or not.
+     * 
+     * @return the transfer type.
+     */
+    public int getTransferType() {
+        return dataType;
+    }
+
+    /**
+     * Returns the number of data elements for pixel transfering
+     * via the getDataElements and setDataElements methods. 
+     * 
+     * @return the number of data elements for pixel transfering
+     * via the getDataElements and setDataElements methods.
+     */
+    public abstract int getNumDataElements();
+
+    /**
+     * Gets the number of bands in the image data of this 
+     * SampleModel object.
+     * 
+     * @return the number of bands in the image data of this 
+     * SampleModel object.
+     */
+    public final int getNumBands() {
+        return numBands;
+    }
+
+    /**
+     * Gets the height of the image data of this SampleModel object.
+     * 
+     * @return the height of the image data of this SampleModel object.
+     */
+    public final int getHeight() {
+        return height;
+    }
+
+    /**
+     * Gets the data type of image data of this SampleModel object.
+     * 
+     * @return the data type of image data of this SampleModel object.
+     */
+    public final int getDataType() {
+        return dataType;
+    }
+
+}
+
diff --git a/awt/java/awt/image/ShortLookupTable.java b/awt/java/awt/image/ShortLookupTable.java
new file mode 100644
index 0000000..77c9c45
--- /dev/null
+++ b/awt/java/awt/image/ShortLookupTable.java
@@ -0,0 +1,132 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Oct 14, 2005
+ */
+
+package java.awt.image;
+
+
+/**
+ * The ShortLookupTable class provides provides functionality for 
+ * lookup operations, and is defined by an input short array for 
+ * bands or components of image and an offset value.
+ * The offset value will be subtracted from the input values before 
+ * indexing the input arrays. The output of a lookup operation is 
+ * represented as an unsigned short array.
+ */
+public class ShortLookupTable extends LookupTable {
+    
+    /** The data. */
+    private short data[][];
+
+    /**
+     * Instantiates a new ShortLookupTable with the specified offset value
+     * and the specified short array which represents lookup table for
+     * all bands.
+     * 
+     * @param offset the offset value.
+     * @param data the data array.
+     */
+    public ShortLookupTable(int offset, short[] data) {
+        super(offset, 1);
+        this.data = new short[1][data.length];
+        // The data array stored as a reference
+        this.data[0] = data;
+    }
+
+    /**
+     * Instantiates a new ShortLookupTable with the specified offset value
+     * and the specified short array of arrays which represents lookup table
+     * for each band.
+     * 
+     * @param offset the offset value.
+     * @param data the data array of arrays for each band.
+     */
+    public ShortLookupTable(int offset, short[][] data) {
+        super(offset, data.length);
+        this.data = new short[data.length][data[0].length];
+        for (int i = 0; i < data.length; i++) {
+            // The data array for each band stored as a reference
+            this.data[i] = data[i];
+        }
+    }
+
+    /**
+     * Gets the lookup table of this ShortLookupTable object. If 
+     * this ShortLookupTable object has one short array for all bands, 
+     * the returned array length is one.
+     * 
+     * @return the lookup table of this ShortLookupTable object.
+     */
+    public final short[][] getTable() {
+        return data;
+    }
+
+    /**
+     * Returns a short array which contains samples of the specified
+     * pixel which is translated with the lookup table of this 
+     * ShortLookupTable object. The resulted array is stored to
+     * the dst array.
+     * 
+     * @param src the source array.
+     * @param dst the destination array where the result can be stored.
+     * 
+     * @return the short array of translated samples of a pixel.
+     */
+    public short[] lookupPixel(short[] src, short[] dst) {
+        if (dst == null) {
+            dst = new short[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+
+    @Override
+    public int[] lookupPixel(int[] src, int[] dst) {
+        if (dst == null) {
+            dst = new int[src.length];
+        }
+
+        int offset = getOffset();
+        if (getNumComponents() == 1) {
+            for (int i = 0; i < src.length; i++) {
+                dst[i] = data[0][src[i]-offset];
+            }
+        } else {
+            for (int i = 0; i < getNumComponents(); i++) {
+                dst[i] = data[i][src[i]-offset];
+            }
+        }
+
+        return dst;
+    }
+}
diff --git a/awt/java/awt/image/SinglePixelPackedSampleModel.java b/awt/java/awt/image/SinglePixelPackedSampleModel.java
new file mode 100644
index 0000000..311395a
--- /dev/null
+++ b/awt/java/awt/image/SinglePixelPackedSampleModel.java
@@ -0,0 +1,508 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The SinglePixelPackedSampleModel class represents pixel data 
+ * where several samples combine to create a single pixel and 
+ * are stored in a single data array element. This class 
+ * supports TYPE_BYTE, TYPE_USHORT, TYPE_INT data types. 
+ */
+public class SinglePixelPackedSampleModel extends SampleModel {
+
+    /** The bit masks. */
+    private int bitMasks[];
+
+    /** The bit offsets. */
+    private int bitOffsets[];
+
+    /** The bit sizes. */
+    private int bitSizes[];
+
+    /** The scanline stride. */
+    private int scanlineStride;
+
+    /** The max bit size. */
+    private int maxBitSize;
+
+    /**
+     * Instantiates a new SinglePixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param bitMasks the bit masks for all the bands.
+     */
+    public SinglePixelPackedSampleModel(int dataType, int w, int h,
+            int bitMasks[]) {
+        this(dataType, w, h, w, bitMasks);
+    }
+
+    /**
+     * Instantiates a new SinglePixelPackedSampleModel with the specified
+     * parameters.
+     * 
+     * @param dataType the data type of the samples.
+     * @param w the width of the image data.
+     * @param h the height of the image data.
+     * @param scanlineStride The scanline stride of the image data.
+     * @param bitMasks the bit masks for all the bands.
+     */
+    public SinglePixelPackedSampleModel(int dataType, int w, int h,
+            int scanlineStride, int bitMasks[]) {
+
+        super(dataType, w, h, bitMasks.length);
+
+        if (dataType != DataBuffer.TYPE_BYTE &&
+                dataType != DataBuffer.TYPE_USHORT &&
+                dataType != DataBuffer.TYPE_INT) {
+            // awt.61=Unsupported data type: {0}
+            throw new IllegalArgumentException(Messages.getString("awt.61", //$NON-NLS-1$
+                    dataType));
+        }
+
+        this.scanlineStride = scanlineStride;
+        this.bitMasks = bitMasks.clone();
+        this.bitOffsets = new int[this.numBands];
+        this.bitSizes = new int[this.numBands];
+
+        this.maxBitSize = 0;
+
+        for (int i = 0; i < this.numBands; i++) {
+            int offset = 0;
+            int size = 0;
+            int mask = bitMasks[i];
+
+            if (mask != 0) {
+                while ((mask & 1) == 0) {
+                    mask >>>= 1;
+                    offset++;
+                }
+
+                while ((mask & 1) == 1) {
+                    mask >>>= 1;
+                    size++;
+                }
+
+                if (mask != 0) {
+                    // awt.62=Wrong mask : {0}
+                    throw new IllegalArgumentException(Messages.getString(
+                            "awt.62", bitMasks[i])); //$NON-NLS-1$
+                }
+            }
+
+            this.bitOffsets[i] = offset;
+            this.bitSizes[i] = size;
+
+            if (this.maxBitSize < size) {
+                this.maxBitSize = size;
+            }
+
+        }
+
+    }
+
+    @Override
+    public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            byte bdata[];
+            if (obj == null) {
+                bdata = new byte[1];
+            } else {
+                bdata = (byte[]) obj;
+            }
+
+            bdata[0] = (byte) data.getElem(y * scanlineStride + x);
+            obj = bdata;
+            break;
+        case DataBuffer.TYPE_USHORT:
+            short sdata[];
+            if (obj == null) {
+                sdata = new short[1];
+            } else {
+                sdata = (short[]) obj;
+            }
+
+            sdata[0] = (short) data.getElem(y * scanlineStride + x);
+            obj = sdata;
+            break;
+        case DataBuffer.TYPE_INT:
+            int idata[];
+            if (obj == null) {
+                idata = new int[1];
+            } else {
+                idata = (int[]) obj;
+            }
+
+            idata[0] = data.getElem(y * scanlineStride + x);
+            obj = idata;
+            break;
+        }
+        return obj;
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object obj, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        switch (getTransferType()) {
+        case DataBuffer.TYPE_BYTE:
+            data.setElem(y * scanlineStride + x, ((byte[]) obj)[0] & 0xff);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data.setElem(y * scanlineStride + x, ((short[]) obj)[0] & 0xffff);
+            break;
+        case DataBuffer.TYPE_INT:
+            data.setElem(y * scanlineStride + x, ((int[]) obj)[0]);
+            break;
+        }
+    }
+
+    /**
+     * Compares this SinglePixelPackedSampleModel object with 
+     * the specified object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if this SinglePixelPackedSampleModel object is 
+     * equal to the specified object, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
+            return false;
+        }
+
+        SinglePixelPackedSampleModel model = (SinglePixelPackedSampleModel) o;
+        return this.width == model.width &&
+                this.height == model.height &&
+                this.numBands == model.numBands &&
+                this.dataType == model.dataType &&
+                Arrays.equals(this.bitMasks, model.bitMasks) &&
+                Arrays.equals(this.bitOffsets, model.bitOffsets) &&
+                Arrays.equals(this.bitSizes, model.bitSizes) &&
+                this.scanlineStride == model.scanlineStride;
+    }
+
+    @Override
+    public SampleModel createSubsetSampleModel(int bands[]) {
+        if (bands.length > this.numBands) {
+            // awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+            throw new RasterFormatException(Messages.getString("awt.64")); //$NON-NLS-1$
+        }
+
+        int masks[] = new int[bands.length];
+        for (int i = 0; i < bands.length; i++) {
+            masks[i] = this.bitMasks[bands[i]];
+        }
+        return new SinglePixelPackedSampleModel(this.dataType, this.width,
+                this.height, this.scanlineStride, masks);
+    }
+
+    @Override
+    public SampleModel createCompatibleSampleModel(int w, int h) {
+        return new SinglePixelPackedSampleModel(this.dataType, w, h,
+                this.bitMasks);
+    }
+
+    @Override
+    public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int pixel[];
+        if (iArray == null) {
+            pixel = new int[this.numBands];
+        } else {
+            pixel = iArray;
+        }
+
+        for (int i = 0; i < this.numBands; i++) {
+            pixel[i] = getSample(x, y, i, data);
+        }
+
+        return pixel;
+    }
+
+    @Override
+    public void setPixel(int x, int y, int iArray[], DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        for (int i = 0; i < this.numBands; i++) {
+            setSample(x, y, i, iArray[i], data);
+        }
+    }
+
+    @Override
+    public int getSample(int x, int y, int b, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int sample = data.getElem(y * scanlineStride + x);
+        return ((sample & this.bitMasks[b]) >>> this.bitOffsets[b]);
+    }
+
+    @Override
+    public int[] getPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int pixels[];
+
+        if (iArray == null) {
+            pixels = new int[w * h * this.numBands];
+        } else {
+            pixels = iArray;
+        }
+
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < this.numBands; n++) {
+                    pixels[idx++] = getSample(j, i, n, data);
+                }
+            }
+        }
+        return pixels;
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages
+                    .getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int idx = 0;
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                for (int n = 0; n < this.numBands; n++) {
+                    setSample(j, i, n, iArray[idx++], data);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s, DataBuffer data) {
+        if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+        int tmp = data.getElem(y * scanlineStride + x);
+        tmp &= ~this.bitMasks[b];
+        tmp |= (s << this.bitOffsets[b]) & this.bitMasks[b];
+        data.setElem(y * scanlineStride + x, tmp);
+    }
+
+    @Override
+    public int[] getSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages
+                    .getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int samples[];
+        int idx = 0;
+
+        if (iArray == null) {
+            samples = new int[w * h];
+        } else {
+            samples = iArray;
+        }
+
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                samples[idx++] = getSample(j, i, b, data);
+            }
+        }
+
+        return samples;
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[],
+            DataBuffer data) {
+        if ((x < 0) || (y < 0) || ((long) x + (long) w > this.width)
+                || ((long) y + (long) h > this.height)) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int idx = 0;
+        for (int i = y; i < y + h; i++) {
+            for (int j = x; j < x + w; j++) {
+                setSample(x + j, y + i, b, iArray[idx++], data);
+            }
+        }
+    }
+
+    @Override
+    public DataBuffer createDataBuffer() {
+        DataBuffer data = null;
+        int size = (this.height - 1) * scanlineStride + width;
+
+        switch (this.dataType) {
+        case DataBuffer.TYPE_BYTE:
+            data = new DataBufferByte(size);
+            break;
+        case DataBuffer.TYPE_USHORT:
+            data = new DataBufferUShort(size);
+            break;
+        case DataBuffer.TYPE_INT:
+            data = new DataBufferInt(size);
+            break;
+        }
+        return data;
+    }
+
+    /**
+     * Gets the offset of the specified pixel in the data array.
+     * 
+     * @param x the X coordinate of the specified pixel.
+     * @param y the Y coordinate of the specified pixel.
+     * 
+     * @return the offset of the specified pixel.
+     */
+    public int getOffset(int x, int y) {
+        return (y * scanlineStride + x);
+    }
+
+    @Override
+    public int getSampleSize(int band) {
+        return bitSizes[band];
+    }
+
+    @Override
+    public int[] getSampleSize() {
+        return bitSizes.clone();
+    }
+
+    /**
+     * Gets an array of the bit offsets of the data array elements. 
+     * 
+     * @return an array of the bit offsets.
+     */
+    public int[] getBitOffsets() {
+        return bitOffsets.clone();
+    }
+
+    /**
+     * Gets an array of the bit masks for all bands.
+     * 
+     * @return an array of the bit masks for all bands.
+     */
+    public int[] getBitMasks() {
+        return bitMasks.clone();
+    }
+
+    /**
+     * Returns a hash code of this MultiPixelPackedSampleModel class.
+     * 
+     * @return the hash code of this MultiPixelPackedSampleModel class.
+     */
+    @Override
+    public int hashCode() {
+        int hash = 0;
+        int tmp = 0;
+
+        hash = width;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= height;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= numBands;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        hash ^= dataType;
+        tmp = hash >>> 24;
+        hash <<= 8;
+        hash |= tmp;
+        for (int element : bitMasks) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bitOffsets) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        for (int element : bitSizes) {
+            hash ^= element;
+            tmp = hash >>> 24;
+            hash <<= 8;
+            hash |= tmp;
+        }
+        hash ^= scanlineStride;
+        return hash;
+    }
+
+    /**
+     * Gets the scanline stride.
+     * 
+     * @return the scanline stride
+     */
+    public int getScanlineStride() {
+        return this.scanlineStride;
+    }
+
+    @Override
+    public int getNumDataElements() {
+        return 1;
+    }
+
+}
+
diff --git a/awt/java/awt/image/TileObserver.java b/awt/java/awt/image/TileObserver.java
new file mode 100644
index 0000000..39ded02
--- /dev/null
+++ b/awt/java/awt/image/TileObserver.java
@@ -0,0 +1,44 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+
+/**
+ * An asynchronous update interface for receiving notifications
+ * about tile information when tiles of a WritableRenderedImage 
+ * become modifiable or unmodifiable.
+ */
+public interface TileObserver {
+
+    /**
+     * This method is called when information about a tile
+     * update is available.
+     * 
+     * @param source the source image.
+     * @param tileX the X index of the tile.
+     * @param tileY the Y index of the tile.
+     * @param willBeWritable parameter which indicates whether
+     * the tile will be grabbed for writing or be released.
+     */
+    public void tileUpdate(WritableRenderedImage source, int tileX, int tileY, boolean willBeWritable);
+
+}
+
diff --git a/awt/java/awt/image/VolatileImage.java b/awt/java/awt/image/VolatileImage.java
new file mode 100644
index 0000000..3b0cfb2
--- /dev/null
+++ b/awt/java/awt/image/VolatileImage.java
@@ -0,0 +1,144 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.ImageCapabilities;
+import java.awt.Transparency;
+
+/**
+ * The VolatileImage abstract class represents an image which can lose 
+ * its contents at any point. VolatileImage objects are device specific.
+ * This class provies methods for checking if operation of this image
+ * are compatible for the GraphicsConfiguration. 
+ */
+public abstract class VolatileImage extends Image
+    // Volatile image implements Transparency since 1.5
+    implements Transparency {
+    
+    /** 
+     * The Constant IMAGE_INCOMPATIBLE indicates that this VolatileImage 
+     * is not applicable for the GraphicsConfiguration object. 
+     */
+    public static final int IMAGE_INCOMPATIBLE = 2;
+
+    /** 
+     * The Constant IMAGE_OK indicates that VolatileImage is ready 
+     * for using.
+     */
+    public static final int IMAGE_OK = 0;
+
+    /** 
+     * The Constant IMAGE_RESTORED indicates that VolatileImage
+     * will be ready to use after restoring. 
+     */
+    public static final int IMAGE_RESTORED = 1;
+
+    /** 
+     * The transparency value of this image. 
+     */
+    protected int transparency = OPAQUE;
+
+    /**
+     * Instantiates a new VolatileImage object.
+     */
+    public VolatileImage() {
+        super();
+    }
+
+    /**
+     * Returns true if rendering data is lost during validating.
+     * This method should be called after rendering operation of image.
+     * 
+     * @return true, if contents lost during validating, false otherwise.
+     */
+
+    public abstract boolean contentsLost();
+
+    /**
+     * Creates a Graphics2D used to draw in this VolatileImage.
+     * 
+     * @return the Graphics2D object.
+     */
+    public abstract Graphics2D createGraphics();
+
+    /**
+     * Gets the ImageCapabilities of this VolatileImage.
+     * 
+     * @return the ImageCapabilities of this VolatileImage.
+     */
+    public abstract ImageCapabilities getCapabilities();
+
+    /**
+     * Gets the height of this VolatileImage.
+     * 
+     * @return the height of this VolatileImage.
+     */
+    public abstract int getHeight();
+
+    /**
+     * Gets a BufferedImage representation of current VolatileImage that
+     * won't be affected by any changes to this VolatileImage.
+     * 
+     * @return a BufferedImage representation of current VolatileImage.
+     */
+    public abstract BufferedImage getSnapshot();
+
+    /**
+     * Gets the width of this VolatileImage.
+     * 
+     * @return the width of this VolatileImage.
+     */
+    public abstract int getWidth();
+
+    /**
+     * Validates the drawing surface of the image if the surface had been 
+     * lost and if the spacified GraphicsConfiguration object is  
+     * applicable to this image. 
+     * 
+     * @param gc GraphicsConfiguration object.
+     * 
+     * @return one of the image status constants: IMAGE_OK, IMAGE_RESTORED or
+     * IMAGE_INCOMPATIBLE.
+     */
+    public abstract int validate(GraphicsConfiguration gc);
+
+    @Override
+    public void flush() {
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        return createGraphics();
+    }
+
+    @Override
+    public ImageProducer getSource() {
+        return getSnapshot().getSource();
+    }
+
+    public int getTransparency() {
+        return transparency;
+    }
+}
diff --git a/awt/java/awt/image/WritableRaster.java b/awt/java/awt/image/WritableRaster.java
new file mode 100644
index 0000000..0893915
--- /dev/null
+++ b/awt/java/awt/image/WritableRaster.java
@@ -0,0 +1,516 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The WritableRaster class provides functionality for 
+ * writing samples and pixel capabilities to the Raster.
+ */
+public class WritableRaster extends Raster {
+
+    /**
+     * Instantiates a new WritableRaster object with the specified 
+     * SampleModel, DataBuffer, rectangular region and parent 
+     * WritableRaster. 
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified DataBuffer.
+     * @param aRegion the rectangular region which defines the new image bounds. 
+     * @param sampleModelTranslate this point defines the translation point
+     * from the SampleModel to the new WritableRaster coordinates.
+     * @param parent the parent of this WritableRaster.
+     */
+    protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Rectangle aRegion, Point sampleModelTranslate,
+            WritableRaster parent) {
+        super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
+    }
+
+    /**
+     * Instantiates a new WritableRaster object with the specified
+     * SampleModel which defines a layout of this WritableRaster and 
+     * DataBuffer objects which defines the image data.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param dataBuffer the specified DataBuffer.
+     * @param origin the point of origin.
+     */
+    protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer,
+            Point origin) {
+        this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
+                sampleModel.width, sampleModel.height), origin, null);
+    }
+
+    /**
+     * Instantiates a new WritableRaster with the specified SampleModel.
+     * 
+     * @param sampleModel the specified SampleModel.
+     * @param origin the origin.
+     */
+    protected WritableRaster(SampleModel sampleModel, Point origin) {
+        this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(
+                origin.x, origin.y, sampleModel.width, sampleModel.height),
+                origin, null);
+    }
+
+    /**
+     * Sets the data for a single pixel from an input Object which 
+     * represents an array of primitive types: DataBuffer.TYPE_BYTE, 
+     * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, 
+     * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param inData the input data.
+     */
+    public void setDataElements(int x, int y, Object inData) {
+        sampleModel.setDataElements(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, inData, dataBuffer);
+    }
+
+    /**
+     * Sets the data elements which represent pixel data to the specified 
+     * rectangle area as a primitive array. The following image data types
+     * are supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 
+     * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, 
+     * or DataBuffer.TYPE_DOUBLE.
+     * 
+     * @param x the X coordinate of the rectangle of pixels.
+     * @param y the Y coordinate of the rectangle of pixels.
+     * @param w the width of the rectangle of pixels.
+     * @param h the height of the rectangle of pixels.
+     * @param inData the array of primitive type data to be set to the
+     * specified area.
+     */
+    public void setDataElements(int x, int y, int w, int h, Object inData) {
+        sampleModel.setDataElements(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, inData, dataBuffer);
+    }
+
+    /**
+     * Creates the child of this WritableRaster by sharing the specified 
+     * rectangular area in this WritableRaster. 
+     * The parentX, parentY, width and height parameters specify rectangular
+     * area to be shared.
+     * 
+     * @param parentX the X coordinate of the upper left corner of 
+     * the shared rectangle with respect to this WritableRaster' coordinates. 
+     * @param parentY the Y coordinate of the upper left corner of 
+     * the shared rectangle with respect to this WritableRaster' coordinates. 
+     * @param w the width of the child area.
+     * @param h the height of the child area.
+     * @param childMinX the X coordinate of child area mapped to the parentX
+     * coordinate.
+     * @param childMinY the Y coordinate of child area mapped to the parentY
+     * coordinate.
+     * @param bandList the array of band indicies.
+     * 
+     * @return the child WritableRaster.
+     */
+    public WritableRaster createWritableChild(int parentX, int parentY, int w,
+            int h, int childMinX, int childMinY, int bandList[]) {
+        if (w <= 0 || h <= 0) {
+            // awt.244=Width or Height of child Raster is less than or equal to zero
+            throw new RasterFormatException(Messages.getString("awt.244")); //$NON-NLS-1$
+        }
+
+        if (parentX < this.minX || parentX + w > this.minX + this.width) {
+            // awt.245=parentX disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.245")); //$NON-NLS-1$
+        }
+
+        if (parentY < this.minY || parentY + h > this.minY + this.height) {
+            // awt.246=parentY disposes outside Raster
+            throw new RasterFormatException(Messages.getString("awt.246")); //$NON-NLS-1$
+        }
+
+        if ((long) parentX + w > Integer.MAX_VALUE) {
+            // awt.247=parentX + w results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.247")); //$NON-NLS-1$
+        }
+
+        if ((long) parentY + h > Integer.MAX_VALUE) {
+            // awt.248=parentY + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.248")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinX + w > Integer.MAX_VALUE) {
+            // awt.249=childMinX + w results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.249")); //$NON-NLS-1$
+        }
+
+        if ((long) childMinY + h > Integer.MAX_VALUE) {
+            // awt.24A=childMinY + h results in integer overflow
+            throw new RasterFormatException(Messages.getString("awt.24A")); //$NON-NLS-1$
+        }
+
+        SampleModel childModel;
+
+        if (bandList == null) {
+            childModel = sampleModel;
+        } else {
+            childModel = sampleModel.createSubsetSampleModel(bandList);
+        }
+
+        int childTranslateX = childMinX - parentX;
+        int childTranslateY = childMinY - parentY;
+
+        return new WritableRaster(childModel, dataBuffer,
+                new Rectangle(childMinX, childMinY, w, h),
+                new Point(childTranslateX + sampleModelTranslateX,
+                        childTranslateY + sampleModelTranslateY),
+                this);
+    }
+
+    /**
+     * Creates the translated child of this WritableRaster. 
+     * New WritableRaster object is a reference to the this 
+     * WritableRaster and with different location. 
+     *  
+     * @param childMinX the X coordinate of the new WritableRaster.
+     * @param childMinY the Y coordinate of the new WritableRaster.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster createWritableTranslatedChild(int childMinX,
+            int childMinY) {
+        return createWritableChild(minX, minY, width, height, childMinX,
+                childMinY, null);
+    }
+
+    /**
+     * Gets the parent WritableRaster for this WritableRaster object. 
+     * 
+     * @return the parent WritableRaster for this WritableRaster object.
+     */
+    public WritableRaster getWritableParent() {
+        return (WritableRaster) parent;
+    }
+
+    /**
+     * Sets pixels from the specified source Raster srcRaster to this 
+     * WritableRaster.
+     * 
+     * @param srcRaster the source Raster.
+     */
+    public void setRect(Raster srcRaster) {
+        setRect(0, 0, srcRaster);
+    }
+
+    /**
+     * Sets pixels from the specified source Raster srcRaster to this 
+     * WritableRaster. Each pixel with (x, y) coordinates from the source 
+     * Raster is copied to pixel with (x+dx, y+dy) coordinates in this
+     * WritableRaster. The pixels with (x+dx, y+dy) coordinates which
+     * are out the bounds of this raster are ignored. 
+     *  
+     * @param dx the distance the pixel's X coordinate in the source
+     * Raster is translated when writtien to this WritableRaster. 
+     * @param dy the distance the pixel's Y coordinate in the source
+     * Raster is translated when writtien to this WritableRaster.
+     * @param srcRaster the source Raster.
+     */
+    public void setRect(int dx, int dy, Raster srcRaster) {
+        int w = srcRaster.getWidth();
+        int h = srcRaster.getHeight();
+
+        int srcX = srcRaster.getMinX();
+        int srcY = srcRaster.getMinY();
+
+        int dstX = srcX + dx;
+        int dstY = srcY + dy;
+
+        if (dstX < this.minX) {
+            int minOffX = this.minX - dstX;
+            w -= minOffX;
+            dstX = this.minX;
+            srcX += minOffX;
+        }
+
+        if (dstY < this.minY) {
+            int minOffY = this.minY - dstY;
+            h -= minOffY;
+            dstY = this.minY;
+            srcY += minOffY;
+        }
+
+        if (dstX + w > this.minX + this.width) {
+            int maxOffX = (dstX + w) - (this.minX + this.width);
+            w -= maxOffX;
+        }
+
+        if (dstY + h > this.minY + this.height) {
+            int maxOffY = (dstY + h) - (this.minY + this.height);
+            h -= maxOffY;
+        }
+
+        if (w <= 0 || h <= 0) {
+            return;
+        }
+
+        switch (sampleModel.getDataType()) {
+        case DataBuffer.TYPE_BYTE:
+        case DataBuffer.TYPE_SHORT:
+        case DataBuffer.TYPE_USHORT:
+        case DataBuffer.TYPE_INT:
+            int iPixelsLine[] = null;
+            for (int i = 0; i < h; i++) {
+                iPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1,
+                        iPixelsLine);
+                setPixels(dstX, dstY + i, w, 1, iPixelsLine);
+            }
+            break;
+
+        case DataBuffer.TYPE_FLOAT:
+            float fPixelsLine[] = null;
+            for (int i = 0; i < h; i++) {
+                fPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1,
+                        fPixelsLine);
+                setPixels(dstX, dstY + i, w, 1, fPixelsLine);
+            }
+            break;
+
+        case DataBuffer.TYPE_DOUBLE:
+            double dPixelsLine[] = null;
+            for (int i = 0; i < h; i++) {
+                dPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1,
+                        dPixelsLine);
+                setPixels(dstX, dstY + i, w, 1, dPixelsLine);
+            }
+            break;
+        }
+    }
+
+    /**
+     * Sets the data for a rectangle of pixels from an input Raster to
+     * this WritableRaster.
+     * 
+     * @param x the X coordinate of the point where the data of 
+     * the input Raster is to be written.
+     * @param y the Y coordinate of the point where the data of 
+     * the input Raster is to be written.
+     * @param inRaster the input Raster.
+     */
+    public void setDataElements(int x, int y, Raster inRaster) {
+        int dstX = x + inRaster.getMinX();
+        int dstY = y + inRaster.getMinY();
+
+        int w = inRaster.getWidth();
+        int h = inRaster.getHeight();
+
+        if (dstX < this.minX || dstX + w > this.minX + this.width ||
+                dstY < this.minY || dstY + h > this.minY + this.height) {
+            // awt.63=Coordinates are not in bounds
+            throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$
+        }
+
+        int srcX = inRaster.getMinX();
+        int srcY = inRaster.getMinY();
+        Object line = null;
+
+        for (int i = 0; i < h; i++) {
+            line = inRaster.getDataElements(srcX, srcY + i, w, 1, line);
+            setDataElements(dstX, dstY + i, w, 1, line);
+        }
+    }
+
+    /**
+     * Sets a int array of samples for the specified pixel 
+     * in this WritableRaster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param iArray the int array of samples.
+     */
+    public void setPixel(int x, int y, int iArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, iArray, dataBuffer);
+    }
+
+    /**
+     * Sets a float array of samples for the specified pixel 
+     * in this WritableRaster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param fArray the float array of samples.
+     */
+    public void setPixel(int x, int y, float fArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, fArray, dataBuffer);
+    }
+
+    /**
+     * Sets a double array of samples for the specified pixel 
+     * in this WritableRaster. 
+     * 
+     * @param x the pixel's X coordinate.
+     * @param y the pixel's Y coordinate.
+     * @param dArray the double array of samples.
+     */
+    public void setPixel(int x, int y, double dArray[]) {
+        sampleModel.setPixel(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, dArray, dataBuffer);
+    }
+
+    /**
+     * Sets a int array of samples for the specified rectangular area
+     * of pixels in this WritableRaster. 
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param iArray the int array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, int iArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, iArray, dataBuffer);
+    }
+
+    /**
+     * Sets a float array of samples for the specified rectangular area
+     * of pixels in this WritableRaster. 
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param fArray the float array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, float fArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, fArray, dataBuffer);
+    }
+
+    /**
+     * Sets a double array of samples for the specified rectangular area
+     * of pixels in this WritableRaster. 
+     * 
+     * @param x the X coordinate of rectangular area.
+     * @param y the Y coordinate of rectangular area.
+     * @param w the width of rectangular area.
+     * @param h the height of rectangular area.
+     * @param dArray the double array of samples.
+     */
+    public void setPixels(int x, int y, int w, int h, double dArray[]) {
+        sampleModel.setPixels(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, dArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified
+     * rectangular area of pixels with an int array of samples.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param b the specified band.
+     * @param iArray the int array of samples.
+
+     */
+    public void setSamples(int x, int y, int w, int h, int b, int iArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified
+     * rectangular area of pixels with a float array of samples.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param b the specified band.
+     * @param fArray the float array of samples.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, float fArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
+    }
+
+    /**
+     * Sets the samples for the specified band and the specified
+     * rectangular area of pixels with a double array of samples.
+     * 
+     * @param x the X coordinate of the area of pixels.
+     * @param y the Y coordinate of the area of pixels.
+     * @param w the width of the area of pixels.
+     * @param h the height of the area of pixels.
+     * @param b the specified band.
+     * @param dArray the double array of samples.
+     */
+    public void setSamples(int x, int y, int w, int h, int b, double dArray[]) {
+        sampleModel.setSamples(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified
+     * pixel with an int sample.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample to be set.
+     */
+    public void setSample(int x, int y, int b, int s) {
+        sampleModel.setSample(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, b, s, dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified
+     * pixel with a float sample.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample to be set.
+     */
+    public void setSample(int x, int y, int b, float s) {
+        sampleModel.setSample(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, b, s, dataBuffer);
+    }
+
+    /**
+     * Sets the sample for the specified band and the specified
+     * pixel with a int sample.
+     * 
+     * @param x the X coordinate of the pixel.
+     * @param y the Y coordinate of the pixel.
+     * @param b the specified band.
+     * @param s the sample to be set.
+     */
+    public void setSample(int x, int y, int b, double s) {
+        sampleModel.setSample(x - sampleModelTranslateX,
+                y - sampleModelTranslateY, b, s, dataBuffer);
+    }
+
+}
+
diff --git a/awt/java/awt/image/WritableRenderedImage.java b/awt/java/awt/image/WritableRenderedImage.java
new file mode 100644
index 0000000..ee1cb9e
--- /dev/null
+++ b/awt/java/awt/image/WritableRenderedImage.java
@@ -0,0 +1,101 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.awt.Point;
+
+/**
+ * The WriteableRenderedImage interface is interface for objects which
+ * contains Raster data of one or several tiles. This interface provides
+ * notification mehanism for obtaining tile's writing status.    
+ */
+public interface WritableRenderedImage extends RenderedImage {
+
+    /**
+     * Gets and checks out the writable tile for writing. 
+     * 
+     * @param tileX the X index of the tile. 
+     * @param tileY the Y index of the tile.
+     * 
+     * @return the WritableRaster.
+     */
+    public WritableRaster getWritableTile(int tileX, int tileY);
+
+    /**
+     * Removes the registered TileObserver.
+     * 
+     * @param to the TileObserver which is registered for this
+     * WritableRenderedImage.
+     */
+    public void removeTileObserver(TileObserver to);
+
+    /**
+     * Adds the specified TileObserver to this WritableRenderedImage.
+     * 
+     * @param to the TileObserver object to be added.
+     */
+    public void addTileObserver(TileObserver to);
+
+    /**
+     * Sets this image to the contents of the specified Raster.  
+     * 
+     * @param r the specified Raster.
+     */
+    public void setData(Raster r);
+
+    /**
+     * Gets the array of points wich represent indices of tiles which
+     * are check out for writing.
+     * 
+     * @return the array of Points.
+     */
+    public Point[] getWritableTileIndices();
+
+    /**
+     * Checks if the specified tile is writable or not.
+     * 
+     * @param tileX the X index of tile. 
+     * @param tileY the Y index of tile.
+     * 
+     * @return true, if the specified tile is writable,
+     * false otherwise.
+     */
+    public boolean isTileWritable(int tileX, int tileY);
+
+    /**
+     * Release the specified writable tile. This method removes the writer 
+     * from the tile.
+     * 
+     * @param tileX the X index of the tile. 
+     * @param tileY the Y index of the tile.
+     */
+    public void releaseWritableTile(int tileX, int tileY);
+
+    /**
+     * Checks if there is a tile which is checked out for writing.
+     * 
+     * @return true, if any tile is checked out for writing, false if there
+     * is no such tile.
+     */
+    public boolean hasTileWriters();
+
+}
+
diff --git a/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java b/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
new file mode 100644
index 0000000..3e96637
--- /dev/null
+++ b/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
@@ -0,0 +1,89 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+
+/**
+ * A factory for creating ContextualRenderedImage objects with utilities 
+ * for manipulating the properties in the parameter block.
+ */
+public interface ContextualRenderedImageFactory extends RenderedImageFactory {
+
+    /**
+     * Maps a render context to a parameter block and a renderable image.
+     * 
+     * @param a0 the index
+     * @param a1 the RenderContext
+     * @param a2 the ParameterBlock
+     * @param a3 the RenderableImage
+     * 
+     * @return the render context
+     */
+    public RenderContext mapRenderContext(int a0, RenderContext a1, ParameterBlock a2, RenderableImage a3);
+
+    /**
+     * Gets the value of the property from the parameter block.
+     * 
+     * @param a0 the parameter block to examine to find the property
+     * @param a1 the name of the property
+     * 
+     * @return the value of the property
+     */
+    public Object getProperty(ParameterBlock a0, String a1);
+
+    /**
+     * Creates the rendered image determined by the render context and
+     * parameter block.
+     * 
+     * @param a0 the RenderContext
+     * @param a1 the ParameterBlock
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage create(RenderContext a0, ParameterBlock a1);
+
+    /**
+     * Gets the bounding rectangle from the parameter block.
+     * 
+     * @param a0 the parameter block to read the bounds from
+     * 
+     * @return the bounding rectangle
+     */
+    public Rectangle2D getBounds2D(ParameterBlock a0);
+
+    /**
+     * Gets the names of all of the supported properties.
+     * 
+     * @return the property names
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Checks if this image factory is dynamic.
+     * 
+     * @return true, if this image factory is dynamic
+     */
+    public boolean isDynamic();
+
+}
+
diff --git a/awt/java/awt/image/renderable/ParameterBlock.java b/awt/java/awt/image/renderable/ParameterBlock.java
new file mode 100644
index 0000000..1555f45
--- /dev/null
+++ b/awt/java/awt/image/renderable/ParameterBlock.java
@@ -0,0 +1,548 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.image.RenderedImage;
+import java.io.Serializable;
+import java.util.Vector;
+
+/**
+ * The Class ParameterBlock groups an indexed set of parameter data 
+ * with a set of renderable (source) images.  The mapping between
+ * the indexed parameters and their property names is provided 
+ * by a {@link ContextualRenderedImageFactory}
+ */
+public class ParameterBlock implements Cloneable, Serializable {
+
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -7577115551785240750L;
+
+    /** The sources (renderable images). */
+    protected Vector<Object> sources = new Vector<Object>();
+
+    /** The parameters. */
+    protected Vector<Object> parameters = new Vector<Object>();
+
+    /**
+     * Instantiates a new parameter block.
+     * 
+     * @param sources the vector of source images
+     * @param parameters the vector of parameters
+     */
+    public ParameterBlock(Vector<Object> sources, Vector<Object> parameters) {
+        setSources(sources);
+        setParameters(parameters);
+    }
+
+    /**
+     * Instantiates a new parameter block with no parameters.
+     * 
+     * @param sources the vector of source images
+     */
+    public ParameterBlock(Vector<Object> sources) {
+        setSources(sources);
+    }
+
+    /**
+     * Instantiates a new parameter block with no image or parameter vectors.
+     */
+    public ParameterBlock() {}
+
+    /**
+     * Sets the source image at the specified index.
+     * 
+     * @param source the source image
+     * @param index the index where the source will be placed
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock setSource(Object source, int index) {
+        if(sources.size() < index + 1){
+            sources.setSize(index + 1);
+        }
+        sources.setElementAt(source, index);
+        return this;
+    }
+
+    /**
+     * Sets the parameter value object at the specified index.
+     * 
+     * @param obj the parameter value to place at the desired index
+     * @param index the index where the object is to be placed in the 
+     * vector of parameters
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(Object obj, int index) {
+        if(parameters.size() < index + 1){
+            parameters.setSize(index + 1);
+        }
+        parameters.setElementAt(obj, index);
+        return this;
+    }
+
+    /**
+     * Adds a source to the vector of sources.
+     * 
+     * @param source the source to add
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock addSource(Object source) {
+        sources.addElement(source);
+        return this;
+    }
+
+    /**
+     * Adds the object to the vector of parameter values
+     * 
+     * @param obj the obj to add
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(Object obj) {
+        parameters.addElement(obj);
+        return this;
+    }
+
+    /**
+     * Sets the vector of sources, replacing the existing
+     * vector of sources, if any.
+     * 
+     * @param sources the new sources
+     */
+    public void setSources(Vector<Object> sources) {
+        this.sources = sources;
+    }
+
+    /**
+     * Sets the vector of parameters, replacing the existing
+     * vector of parameters, if any.
+     * 
+     * @param parameters the new parameters
+     */
+    public void setParameters(Vector<Object> parameters) {
+        this.parameters = parameters;
+    }
+
+    /**
+     * Gets the vector of sources.
+     * 
+     * @return the sources
+     */
+    public Vector<Object> getSources() {
+        return sources;
+    }
+
+    /**
+     * Gets the vector of parameters.
+     * 
+     * @return the parameters
+     */
+    public Vector<Object> getParameters() {
+        return parameters;
+    }
+
+    /**
+     * Gets the source at the specified index.
+     * 
+     * @param index the index
+     * 
+     * @return the source object found at the specified index
+     */
+    public Object getSource(int index) {
+        return sources.elementAt(index);
+    }
+
+    /**
+     * Gets the object parameter found at the specified index.
+     * 
+     * @param index the index
+     * 
+     * @return the parameter object found at the specified index
+     */
+    public Object getObjectParameter(int index) {
+        return parameters.elementAt(index);
+    }
+
+    /**
+     * Shallow clone (clones using the superclass clone method).
+     * 
+     * @return the clone of this object
+     */
+    public Object shallowClone() {
+        try{
+            return super.clone();
+        }catch(Exception e){
+            return null;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object clone() {
+        ParameterBlock replica;
+        try{
+            replica = (ParameterBlock)super.clone();
+        }catch(Exception e){
+            return null;
+        }
+        if(sources != null){
+            replica.setSources((Vector<Object>)(sources.clone()));
+        }
+        if(parameters != null){
+            replica.setParameters((Vector<Object>)(parameters.clone()));
+        }
+        return replica;
+    }
+
+    /**
+     * Gets an array of classes corresponding to all of the parameter
+     * values found in the array of parameters, in order.
+     * 
+     * @return the parameter classes
+     */
+    public Class[] getParamClasses() {
+        int count = parameters.size();
+        Class paramClasses[] = new Class[count];
+
+        for(int i = 0; i < count; i++){
+            paramClasses[i] = parameters.elementAt(i).getClass();
+        }
+        return paramClasses;
+    }
+
+    /**
+     * Gets the renderable source image found at the specified index
+     * in the source array.
+     * 
+     * @param index the index
+     * 
+     * @return the renderable source image
+     */
+    public RenderableImage getRenderableSource(int index) {
+        return (RenderableImage)sources.elementAt(index);
+    }
+
+    /**
+     * Wraps the short value in a Short and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param s the short value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(short s, int index) {
+        return set(new Short(s), index);
+    }
+
+    /**
+     * Wraps the short value in a Short and adds it to the 
+     * parameter block.
+     * 
+     * @param s the short value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(short s) {
+        return add(new Short(s));
+    }
+
+    /**
+     * Wraps the long value in a Long and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param l the long value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(long l, int index) {
+        return set(new Long(l), index);
+    }
+
+    /**
+     * Wraps the long value in a Long and adds it to the 
+     * parameter block.
+     * 
+     * @param l the long value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(long l) {
+        return add(new Long(l));
+    }
+
+    /**
+     * Wraps the int value in an Integer and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param i the int value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(int i, int index) {
+        return set(new Integer(i), index);
+    }
+
+    /**
+     * Wraps the int value in an Integer and adds it to the 
+     * parameter block.
+     * 
+     * @param i the int value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(int i) {
+        return add(new Integer(i));
+    }
+
+    /**
+     * Wraps the float value in a Float and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param f the float value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(float f, int index) {
+        return set(new Float(f), index);
+    }
+
+    /**
+     * Wraps the float value in a Float and adds it to the 
+     * parameter block.
+     * 
+     * @param f the float value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(float f) {
+        return add(new Float(f));
+    }
+
+    /**
+     * Wraps the double value in a Double and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param d the double value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(double d, int index) {
+        return set(new Double(d), index);
+    }
+
+    /**
+     * Wraps the double value in a Double and adds it to the 
+     * parameter block.
+     * 
+     * @param d the double value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(double d) {
+        return add(new Double(d));
+    }
+
+    /**
+     * Wraps the char value in a Character and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param c the char value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(char c, int index) {
+        return set(new Character(c), index);
+    }
+
+    /**
+     * Wraps the char value in a Character and adds it to the 
+     * parameter block.
+     * 
+     * @param c the char value of the parameter
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock add(char c) {
+        return add(new Character(c));
+    }
+
+    /**
+     * Wraps the byte value in a Byte and places it in the 
+     * parameter block at the specified index.
+     * 
+     * @param b the byte value of the parameter
+     * @param index the index
+     * 
+     * @return this parameter block
+     */
+    public ParameterBlock set(byte b, int index) {
+        return set(new Byte(b), index);
+    }
+
+    /**
+     * Wraps the byte value in a Byte and adds it to the 
+     * parameter block.
+     * 
+     * @param b the byte value of the parameter
+     * 
+     * @return the parameter block
+     */
+    public ParameterBlock add(byte b) {
+        return add(new Byte(b));
+    }
+
+    /**
+     * Gets the RenderedImage at the specified index from the 
+     * vector of source images.
+     * 
+     * @param index the index
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage getRenderedSource(int index) {
+        return (RenderedImage)sources.elementAt(index);
+    }
+
+    /**
+     * Gets the short-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the short parameter
+     */
+    public short getShortParameter(int index) {
+        return ((Short)parameters.elementAt(index)).shortValue();
+    }
+
+    /**
+     * Gets the long-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the long parameter
+     */
+    public long getLongParameter(int index) {
+        return ((Long)parameters.elementAt(index)).longValue();
+    }
+
+    /**
+     * Gets the int-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the int parameter
+     */
+    public int getIntParameter(int index) {
+        return ((Integer)parameters.elementAt(index)).intValue();
+    }
+
+    /**
+     * Gets the float-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the float parameter
+     */
+    public float getFloatParameter(int index) {
+        return ((Float)parameters.elementAt(index)).floatValue();
+    }
+
+    /**
+     * Gets the double-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the double parameter
+     */
+    public double getDoubleParameter(int index) {
+        return ((Double)parameters.elementAt(index)).doubleValue();
+    }
+
+    /**
+     * Gets the char-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the char parameter
+     */
+    public char getCharParameter(int index) {
+        return ((Character)parameters.elementAt(index)).charValue();
+    }
+
+    /**
+     * Gets the byte-valued parameter found at the desired index
+     * in the vector of parameter values.
+     * 
+     * @param index the index
+     * 
+     * @return the byte parameter
+     */
+    public byte getByteParameter(int index) {
+        return ((Byte)parameters.elementAt(index)).byteValue();
+    }
+
+    /**
+     * Clears the vector of sources.
+     */
+    public void removeSources() {
+        sources.removeAllElements();
+    }
+
+    /**
+     * Clears the vector of parameters.
+     */
+    public void removeParameters() {
+        parameters.removeAllElements();
+    }
+
+    /**
+     * Gets the number of elements in the vector of sources.
+     * 
+     * @return the number of elements in the vector of sources
+     */
+    public int getNumSources() {
+        return sources.size();
+    }
+
+    /**
+     * Gets the number of elements in the vector of parameters.
+     * 
+     * @return the number of elements in the vector of parameters
+     */
+    public int getNumParameters() {
+        return parameters.size();
+    }
+}
diff --git a/awt/java/awt/image/renderable/RenderContext.java b/awt/java/awt/image/renderable/RenderContext.java
new file mode 100644
index 0000000..3a3b93c
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderContext.java
@@ -0,0 +1,196 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+
+/**
+ * The Class RenderContext stores data on how an image is to be 
+ * rendered: the affine transform, the area of interest, and 
+ * the rendering hints.
+ */
+public class RenderContext implements Cloneable {
+
+    /** The affine transform. */
+    AffineTransform transform;
+    
+    /** The area of interest. */
+    Shape aoi;
+    
+    /** The rendering hints. */
+    RenderingHints hints;
+
+    /**
+     * Instantiates a new render context.
+     * 
+     * @param usr2dev the affine transform
+     * @param aoi the area of interest
+     * @param hints the rendering hints
+     */
+    public RenderContext(AffineTransform usr2dev, Shape aoi, RenderingHints hints) {
+        this.transform = (AffineTransform)usr2dev.clone();
+        this.aoi = aoi;
+        this.hints = hints;
+    }
+
+    /**
+     * Instantiates a new render context with no specified hints.
+     * 
+     * @param usr2dev the affine transform
+     * @param aoi the area of interest
+     */
+    public RenderContext(AffineTransform usr2dev, Shape aoi) {
+        this(usr2dev, aoi, null);
+    }
+
+    /**
+     * Instantiates a new render context with no specified area of interest.
+     * 
+     * @param usr2dev the affine transform
+     * @param hints the rendering hints
+     */
+    public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
+        this(usr2dev, null, hints);
+    }
+
+    /**
+     * Instantiates a new render context with no rendering hints or 
+     * area of interest.
+     * 
+     * @param usr2dev the affine transform
+     */
+    public RenderContext(AffineTransform usr2dev) {
+        this(usr2dev, null, null);
+    }
+
+    @Override
+    public Object clone() {
+        return new RenderContext(transform, aoi, hints);
+    }
+
+    /**
+     * Sets the affine transform for this render context.
+     * 
+     * @param newTransform the new affine transform
+     */
+    public void setTransform(AffineTransform newTransform) {
+        transform = (AffineTransform)newTransform.clone();
+    }
+
+    /**
+     * Concatenates the current transform with the specified transform
+     * (so they are applied with the specified transform acting first)
+     * and sets the resulting transform as the affine transform of 
+     * this rendering context.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     * 
+     * @deprecated use {@link RenderContext#preConcatenateTransform(AffineTransform)}
+     */
+    @Deprecated    
+    public void preConcetenateTransform(AffineTransform modTransform) {
+        preConcatenateTransform(modTransform);
+    }
+
+    /**
+     * Concatenates the current transform with the specified transform
+     * (so they are applied with the specified transform acting first)
+     * and sets the resulting transform as the affine transform of 
+     * this rendering context.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     */
+    public void preConcatenateTransform(AffineTransform modTransform) {
+        transform.preConcatenate(modTransform);
+    }
+
+    /**
+     * Concatenate the specified transform with the current transform.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     * 
+     * @deprecated use {@link RenderContext#concatenateTransform(AffineTransform)}
+     */
+    @Deprecated
+    public void concetenateTransform(AffineTransform modTransform) {
+        concatenateTransform(modTransform);
+    }
+
+    /**
+     * Concatenate the specified transform with the current transform.
+     * 
+     * @param modTransform the new transform which modifies the 
+     * current transform
+     */
+    public void concatenateTransform(AffineTransform modTransform) {
+        transform.concatenate(modTransform);
+    }
+
+    /**
+     * Gets the transform.
+     * 
+     * @return the transform
+     */
+    public AffineTransform getTransform() {
+        return (AffineTransform)transform.clone();
+    }
+
+    /**
+     * Sets the area of interest.
+     * 
+     * @param newAoi the new area of interest
+     */
+    public void setAreaOfInterest(Shape newAoi) {
+        aoi = newAoi;
+    }
+
+    /**
+     * Gets the area of interest.
+     * 
+     * @return the area of interest
+     */
+    public Shape getAreaOfInterest() {
+        return aoi;
+    }
+
+    /**
+     * Sets the rendering hints.
+     * 
+     * @param hints the new rendering hints
+     */
+    public void setRenderingHints(RenderingHints hints) {
+        this.hints = hints;
+    }
+
+    /**
+     * Gets the rendering hints.
+     * 
+     * @return the rendering hints
+     */
+    public RenderingHints getRenderingHints() {
+        return hints;
+    }
+}
diff --git a/awt/java/awt/image/renderable/RenderableImage.java b/awt/java/awt/image/renderable/RenderableImage.java
new file mode 100644
index 0000000..885dc06
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImage.java
@@ -0,0 +1,132 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+/**
+ * The Interface RenderableImage is implemented by an object that
+ * collects all of the image-specific data that defines a single image 
+ * that could be rendered to different rendering targets.
+ */
+public interface RenderableImage {
+
+    /** The Constant HINTS_OBSERVED indicates that the rendering
+     * hints are applied rather than ignored. */
+    public static final String HINTS_OBSERVED = "HINTS_OBSERVED"; //$NON-NLS-1$
+
+    /**
+     * Gets the property from the RenderableImage's parameter block.
+     * 
+     * @param name the name of the property to get.
+     * 
+     * @return the value of the property
+     */
+    public Object getProperty(String name);
+
+    /**
+     * Creates the rendered image based on the information contained 
+     * in the parameters and the render context.
+     * 
+     * @param renderContext the render context giving rendering specifications
+     * such as transformations
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage createRendering(RenderContext renderContext);
+
+    /**
+     * Creates the scaled rendered image based on the information contained 
+     * in the parameters and the render context.
+     * 
+     * @param w the desired width after scaling or zero if the scaling 
+     * should be proportional, based on the height
+     * @param h the desired height after scaling or zero if the scaling 
+     * should be proportional, based on the width
+     * @param hints the rendering hints to use
+     * 
+     * @return the rendered image
+     * 
+     * @throws IllegalArgumentException if both the height and width are zero
+     */
+    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
+
+    /**
+     * Gets the vector of sources from the parameter block.
+     * 
+     * @return the sources
+     */
+    public Vector<RenderableImage> getSources();
+
+    /**
+     * Gets the names of all of the supported properties in the current context.
+     * 
+     * @return the property names
+     */
+    public String[] getPropertyNames();
+
+    /**
+     * Creates the default rendering (using the identity transform
+     * and default render context).
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage createDefaultRendering();
+
+    /**
+     * Checks if this context supports dynamic rendering.
+     * 
+     * @return true, if this context supports dynamic rendering
+     */
+    public boolean isDynamic();
+
+    /**
+     * Gets the width of the image.
+     * 
+     * @return the width of the image
+     */
+    public float getWidth();
+
+    /**
+     * Gets the y coordinate of the upper left corner.
+     * 
+     * @return the y coordinate of the upper left corner
+     */
+    public float getMinY();
+
+    /**
+     * Gets the x coordinate of the upper left corner.
+     * 
+     * @return the x coordinate of the upper left corner
+     */
+    public float getMinX();
+
+    /**
+     * Gets the height of the image.
+     * 
+     * @return the height of the image
+     */
+    public float getHeight();
+
+}
+
diff --git a/awt/java/awt/image/renderable/RenderableImageOp.java b/awt/java/awt/image/renderable/RenderableImageOp.java
new file mode 100644
index 0000000..993ba5f
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImageOp.java
@@ -0,0 +1,182 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * The Class RenderableImageOp is a basic implementation of RenderableImage, 
+ * with methods to access the parameter data and perform rendering
+ * operations.
+ */
+public class RenderableImageOp implements RenderableImage {
+
+    /** The CRIF. */
+    ContextualRenderedImageFactory CRIF;
+    
+    /** The param block. */
+    ParameterBlock paramBlock;
+    
+    /** The height. */
+    float minX, minY, width, height;
+
+    /**
+     * Instantiates a new renderable image op.
+     * 
+     * @param CRIF the cRIF
+     * @param paramBlock the param block
+     */
+    public RenderableImageOp(ContextualRenderedImageFactory CRIF, ParameterBlock paramBlock) {
+        this.CRIF = CRIF;
+        this.paramBlock = (ParameterBlock) paramBlock.clone();
+        Rectangle2D r = CRIF.getBounds2D(paramBlock);
+        minX = (float) r.getMinX();
+        minY = (float) r.getMinY();
+        width = (float) r.getWidth();
+        height = (float) r.getHeight();
+    }
+
+    public Object getProperty(String name) {
+        return CRIF.getProperty(paramBlock, name);
+    }
+
+    /**
+     * Sets the parameter block.
+     * 
+     * @param paramBlock the param block
+     * 
+     * @return the parameter block
+     */
+    public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
+        ParameterBlock oldParam = this.paramBlock;
+        this.paramBlock = (ParameterBlock) paramBlock.clone();
+        return oldParam;
+    }
+
+    public RenderedImage createRendering(RenderContext renderContext) {
+
+        Vector<RenderableImage> sources = getSources();
+        ParameterBlock rdParam = (ParameterBlock) paramBlock.clone();
+
+        if (sources != null) {
+            Vector<Object> rdSources = new Vector<Object>();
+            int i = 0;
+            while (i < sources.size()) {
+                RenderContext newContext = CRIF.mapRenderContext(i, renderContext, paramBlock,
+                        this);
+                RenderedImage rdim = sources.elementAt(i).createRendering(newContext);
+
+                if (rdim != null) {
+                    rdSources.addElement(rdim);
+                }
+                i++;
+            }
+            if (rdSources.size() > 0) {
+                rdParam.setSources(rdSources);
+            }
+        }
+        return CRIF.create(renderContext, rdParam);
+    }
+
+    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints) {
+        if(w == 0 && h == 0) {
+            // awt.60=Width and Height mustn't be equal zero both
+            throw new IllegalArgumentException(Messages.getString("awt.60")); //$NON-NLS-1$
+        }
+        if(w == 0){
+            w = Math.round(h*(getWidth()/getHeight()));
+        }
+
+        if(h == 0){
+            h = Math.round(w*(getHeight()/getWidth()));
+        }
+
+        double sx = (double)w/getWidth();
+        double sy = (double)h/getHeight();
+
+        AffineTransform at = AffineTransform.getScaleInstance(sx, sy);
+        RenderContext context = new RenderContext(at, hints);
+        return createRendering(context);
+    }
+
+    public Vector<RenderableImage> getSources() {
+        if(paramBlock.getNumSources() == 0) {
+            return null;
+        }
+        Vector<RenderableImage> v = new Vector<RenderableImage>();
+        int  i = 0;
+        while(i < paramBlock.getNumSources()){
+            Object o = paramBlock.getSource(i);
+            if(o instanceof RenderableImage){
+                v.addElement((RenderableImage) o);
+            }
+            i++;
+        }
+        return v;
+    }
+
+    public String[] getPropertyNames() {
+        return CRIF.getPropertyNames();
+    }
+
+    /**
+     * Gets the parameter block.
+     * 
+     * @return the parameter block
+     */
+    public ParameterBlock getParameterBlock() {
+        return paramBlock;
+    }
+
+    public RenderedImage createDefaultRendering() {
+        AffineTransform at = new AffineTransform();
+        RenderContext context = new RenderContext(at);
+        return createRendering(context);
+    }
+
+    public boolean isDynamic() {
+        return CRIF.isDynamic();
+    }
+
+    public float getWidth() {
+        return width;
+    }
+
+    public float getMinY() {
+        return minY;
+    }
+
+    public float getMinX() {
+        return minX;
+    }
+
+    public float getHeight() {
+        return height;
+    }
+
+}
+
diff --git a/awt/java/awt/image/renderable/RenderableImageProducer.java b/awt/java/awt/image/renderable/RenderableImageProducer.java
new file mode 100644
index 0000000..7fda98c
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderableImageProducer.java
@@ -0,0 +1,141 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.image.ColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.util.Vector;
+
+/**
+ * The Class RenderableImageProducer provides the implementation for 
+ * the image rendering.
+ */
+public class RenderableImageProducer implements ImageProducer, Runnable {
+
+    /** The rbl. */
+    RenderableImage rbl;
+    
+    /** The rc. */
+    RenderContext rc;
+    
+    /** The consumers. */
+    Vector<ImageConsumer> consumers = new Vector<ImageConsumer>();
+
+    /**
+     * Instantiates a new renderable image producer.
+     * 
+     * @param rdblImage the rdbl image
+     * @param rc the rc
+     */
+    public RenderableImageProducer(RenderableImage rdblImage, RenderContext rc) {
+        this.rbl = rdblImage;
+        this.rc = rc;
+    }
+
+    /**
+     * Sets the render context.
+     * 
+     * @param rc the new render context
+     */
+    public synchronized void setRenderContext(RenderContext rc) {
+        this.rc = rc;
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        return consumers.contains(ic);
+    }
+
+    public synchronized void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+        Thread t = new Thread(this, "RenderableImageProducer thread"); //$NON-NLS-1$
+        t.start();
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {}
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        if(ic != null) {
+            consumers.removeElement(ic);
+        }
+    }
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if(ic != null && !consumers.contains(ic)){
+            consumers.addElement(ic);
+        }
+    }
+
+    /**
+     * Creates the rendered image in a new thread.
+     */
+    public void run() {
+        if(rbl == null) {
+            return;
+        }
+
+        RenderedImage rd;
+        if(rc != null) {
+            rd = rbl.createRendering(rc);
+        } else {
+            rd = rbl.createDefaultRendering();
+        }
+
+        ColorModel cm = rd.getColorModel();
+        if(cm == null) {
+            cm = ColorModel.getRGBdefault();
+        }
+
+        Raster r = rd.getData();
+        int w = r.getWidth();
+        int h = r.getHeight();
+
+        for (ImageConsumer c : consumers) {
+            c.setDimensions(w, h);
+            c.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
+                    ImageConsumer.COMPLETESCANLINES |
+                    ImageConsumer.SINGLEFRAME |
+                    ImageConsumer.SINGLEPASS);
+        }
+
+        int scanLine[] = new int[w];
+        int pixel[] = null;
+
+        for(int y = 0; y < h; y++){
+            for(int x = 0; x < w; x++){
+                pixel = r.getPixel(x, y, pixel);
+                scanLine[x] = cm.getDataElement(pixel, 0);
+            }
+
+            for (ImageConsumer c : consumers) {
+                c.setPixels(0, y, w, 1, cm, scanLine, 0, w);
+            }
+        }
+
+        for (ImageConsumer c : consumers) {
+            c.imageComplete(ImageConsumer.STATICIMAGEDONE);
+        }
+    }
+
+}
+
diff --git a/awt/java/awt/image/renderable/RenderedImageFactory.java b/awt/java/awt/image/renderable/RenderedImageFactory.java
new file mode 100644
index 0000000..345d82c
--- /dev/null
+++ b/awt/java/awt/image/renderable/RenderedImageFactory.java
@@ -0,0 +1,43 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image.renderable;
+
+import java.awt.RenderingHints;
+import java.awt.image.RenderedImage;
+
+/**
+ * A factory for creating RenderedImage objects based on parameters
+ * and rendering hints.
+ */
+public interface RenderedImageFactory {
+
+    /**
+     * Creates the rendered image.
+     * 
+     * @param a0 the ParameterBlock
+     * @param a1 the RenderingHints
+     * 
+     * @return the rendered image
+     */
+    public RenderedImage create(ParameterBlock a0, RenderingHints a1);
+
+}
+
diff --git a/awt/java/awt/peer/ButtonPeer.java b/awt/java/awt/peer/ButtonPeer.java
new file mode 100644
index 0000000..cc45b49
--- /dev/null
+++ b/awt/java/awt/peer/ButtonPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ButtonPeer {
+
+}
diff --git a/awt/java/awt/peer/CanvasPeer.java b/awt/java/awt/peer/CanvasPeer.java
new file mode 100644
index 0000000..e276366
--- /dev/null
+++ b/awt/java/awt/peer/CanvasPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface CanvasPeer {
+
+}
diff --git a/awt/java/awt/peer/CheckboxMenuItemPeer.java b/awt/java/awt/peer/CheckboxMenuItemPeer.java
new file mode 100644
index 0000000..296f422
--- /dev/null
+++ b/awt/java/awt/peer/CheckboxMenuItemPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface CheckboxMenuItemPeer {
+
+}
diff --git a/awt/java/awt/peer/CheckboxPeer.java b/awt/java/awt/peer/CheckboxPeer.java
new file mode 100644
index 0000000..e9f8dd1
--- /dev/null
+++ b/awt/java/awt/peer/CheckboxPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface CheckboxPeer {
+
+}
diff --git a/awt/java/awt/peer/ChoicePeer.java b/awt/java/awt/peer/ChoicePeer.java
new file mode 100644
index 0000000..57b7629
--- /dev/null
+++ b/awt/java/awt/peer/ChoicePeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ChoicePeer {
+
+}
diff --git a/awt/java/awt/peer/ComponentPeer.java b/awt/java/awt/peer/ComponentPeer.java
new file mode 100644
index 0000000..bc26791
--- /dev/null
+++ b/awt/java/awt/peer/ComponentPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ComponentPeer {
+
+}
diff --git a/awt/java/awt/peer/DialogPeer.java b/awt/java/awt/peer/DialogPeer.java
new file mode 100644
index 0000000..8ae3049
--- /dev/null
+++ b/awt/java/awt/peer/DialogPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface DialogPeer {
+
+}
diff --git a/awt/java/awt/peer/FileDialogPeer.java b/awt/java/awt/peer/FileDialogPeer.java
new file mode 100644
index 0000000..0d15e48
--- /dev/null
+++ b/awt/java/awt/peer/FileDialogPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface FileDialogPeer {
+
+}
diff --git a/awt/java/awt/peer/FontPeer.java b/awt/java/awt/peer/FontPeer.java
new file mode 100644
index 0000000..fd9815f
--- /dev/null
+++ b/awt/java/awt/peer/FontPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface FontPeer {
+
+}
diff --git a/awt/java/awt/peer/FramePeer.java b/awt/java/awt/peer/FramePeer.java
new file mode 100644
index 0000000..9cfc40b
--- /dev/null
+++ b/awt/java/awt/peer/FramePeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface FramePeer {
+
+}
diff --git a/awt/java/awt/peer/LabelPeer.java b/awt/java/awt/peer/LabelPeer.java
new file mode 100644
index 0000000..052ca9d
--- /dev/null
+++ b/awt/java/awt/peer/LabelPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface LabelPeer {
+
+}
diff --git a/awt/java/awt/peer/LightweightPeer.java b/awt/java/awt/peer/LightweightPeer.java
new file mode 100644
index 0000000..1dee905
--- /dev/null
+++ b/awt/java/awt/peer/LightweightPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface LightweightPeer {
+
+}
diff --git a/awt/java/awt/peer/ListPeer.java b/awt/java/awt/peer/ListPeer.java
new file mode 100644
index 0000000..0a27885
--- /dev/null
+++ b/awt/java/awt/peer/ListPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ListPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuBarPeer.java b/awt/java/awt/peer/MenuBarPeer.java
new file mode 100644
index 0000000..3ad2c16
--- /dev/null
+++ b/awt/java/awt/peer/MenuBarPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuBarPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuComponentPeer.java b/awt/java/awt/peer/MenuComponentPeer.java
new file mode 100644
index 0000000..3ac3b34
--- /dev/null
+++ b/awt/java/awt/peer/MenuComponentPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuComponentPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuItemPeer.java b/awt/java/awt/peer/MenuItemPeer.java
new file mode 100644
index 0000000..b133897
--- /dev/null
+++ b/awt/java/awt/peer/MenuItemPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuItemPeer {
+
+}
diff --git a/awt/java/awt/peer/MenuPeer.java b/awt/java/awt/peer/MenuPeer.java
new file mode 100644
index 0000000..d643ce7
--- /dev/null
+++ b/awt/java/awt/peer/MenuPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MenuPeer {
+
+}
diff --git a/awt/java/awt/peer/MouseInfoPeer.java b/awt/java/awt/peer/MouseInfoPeer.java
new file mode 100644
index 0000000..9173a62
--- /dev/null
+++ b/awt/java/awt/peer/MouseInfoPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface MouseInfoPeer {
+
+}
diff --git a/awt/java/awt/peer/PanelPeer.java b/awt/java/awt/peer/PanelPeer.java
new file mode 100644
index 0000000..1faa1fe
--- /dev/null
+++ b/awt/java/awt/peer/PanelPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface PanelPeer {
+
+}
diff --git a/awt/java/awt/peer/PopupMenuPeer.java b/awt/java/awt/peer/PopupMenuPeer.java
new file mode 100644
index 0000000..cf1ef61
--- /dev/null
+++ b/awt/java/awt/peer/PopupMenuPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface PopupMenuPeer {
+
+}
diff --git a/awt/java/awt/peer/ScrollPanePeer.java b/awt/java/awt/peer/ScrollPanePeer.java
new file mode 100644
index 0000000..df3de83
--- /dev/null
+++ b/awt/java/awt/peer/ScrollPanePeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ScrollPanePeer {
+
+}
diff --git a/awt/java/awt/peer/ScrollbarPeer.java b/awt/java/awt/peer/ScrollbarPeer.java
new file mode 100644
index 0000000..eec8961
--- /dev/null
+++ b/awt/java/awt/peer/ScrollbarPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface ScrollbarPeer {
+
+}
diff --git a/awt/java/awt/peer/TextAreaPeer.java b/awt/java/awt/peer/TextAreaPeer.java
new file mode 100644
index 0000000..636707f
--- /dev/null
+++ b/awt/java/awt/peer/TextAreaPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface TextAreaPeer {
+
+}
diff --git a/awt/java/awt/peer/TextFieldPeer.java b/awt/java/awt/peer/TextFieldPeer.java
new file mode 100644
index 0000000..2b8232a
--- /dev/null
+++ b/awt/java/awt/peer/TextFieldPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface TextFieldPeer {
+
+}
diff --git a/awt/java/awt/peer/WindowPeer.java b/awt/java/awt/peer/WindowPeer.java
new file mode 100644
index 0000000..384646f
--- /dev/null
+++ b/awt/java/awt/peer/WindowPeer.java
@@ -0,0 +1,25 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package java.awt.peer;
+
+public interface WindowPeer {
+
+}
diff --git a/awt/java/beans/FeatureDescriptor.java b/awt/java/beans/FeatureDescriptor.java
new file mode 100644
index 0000000..2945c65
--- /dev/null
+++ b/awt/java/beans/FeatureDescriptor.java
@@ -0,0 +1,234 @@
+/*
+ * 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 java.beans;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+/**
+ * Common base class for Descriptors.
+ */
+public class FeatureDescriptor {
+
+    private Map<String, Object> values;
+
+    boolean preferred, hidden, expert;
+
+    String shortDescription;
+
+    String name;
+
+    String displayName;
+
+    /**
+     * <p>
+     * Constructs an instance.
+     * </p>
+     */
+    public FeatureDescriptor() {
+        this.values = new HashMap<String, Object>();
+    }
+
+    /**
+     * <p>
+     * Sets the value for the named attribute.
+     * </p>
+     * 
+     * @param attributeName
+     *            The name of the attribute to set a value with.
+     * @param value
+     *            The value to set.
+     */
+    public void setValue(String attributeName, Object value) {
+        if (attributeName == null || value == null) {
+            throw new NullPointerException();
+        }
+        values.put(attributeName, value);
+    }
+
+    /**
+     * <p>
+     * Gets the value associated with the named attribute.
+     * </p>
+     * 
+     * @param attributeName
+     *            The name of the attribute to get a value for.
+     * @return The attribute's value.
+     */
+    public Object getValue(String attributeName) {
+        Object result = null;
+        if (attributeName != null) {
+            result = values.get(attributeName);
+        }
+        return result;
+    }
+
+    /**
+     * <p>
+     * Enumerates the attribute names.
+     * </p>
+     * 
+     * @return An instance of {@link Enumeration}.
+     */
+    public Enumeration<String> attributeNames() {
+        // Create a new list, so that the references are copied
+        return Collections.enumeration(new LinkedList<String>(values.keySet()));
+    }
+
+    /**
+     * <p>
+     * Sets the short description.
+     * </p>
+     * 
+     * @param text
+     *            The description to set.
+     */
+    public void setShortDescription(String text) {
+        this.shortDescription = text;
+    }
+
+    /**
+     * <p>
+     * Sets the name.
+     * </p>
+     * 
+     * @param name
+     *            The name to set.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * <p>
+     * Sets the display name.
+     * </p>
+     * 
+     * @param displayName
+     *            The display name to set.
+     */
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    /**
+     * <p>
+     * Gets the short description or {@link #getDisplayName()} if not set.
+     * </p>
+     * 
+     * @return The description.
+     */
+    public String getShortDescription() {
+        return shortDescription == null ? getDisplayName() : shortDescription;
+    }
+
+    /**
+     * <p>
+     * Gets the name.
+     * </p>
+     * 
+     * @return The name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * <p>
+     * Gets the display name or {@link #getName()} if not set.
+     * </p>
+     * 
+     * @return The display name.
+     */
+    public String getDisplayName() {
+        return displayName == null ? getName() : displayName;
+    }
+
+    /**
+     * <p>
+     * Sets the preferred indicator.
+     * </p>
+     * 
+     * @param preferred
+     *            <code>true</code> if preferred, <code>false</code>
+     *            otherwise.
+     */
+    public void setPreferred(boolean preferred) {
+        this.preferred = preferred;
+    }
+
+    /**
+     * <p>
+     * Sets the hidden indicator.
+     * </p>
+     * 
+     * @param hidden
+     *            <code>true</code> if hidden, <code>false</code> otherwise.
+     */
+    public void setHidden(boolean hidden) {
+        this.hidden = hidden;
+    }
+
+    /**
+     * <p>
+     * Sets the expert indicator.
+     * </p>
+     * 
+     * @param expert
+     *            <code>true</code> if expert, <code>false</code> otherwise.
+     */
+    public void setExpert(boolean expert) {
+        this.expert = expert;
+    }
+
+    /**
+     * <p>
+     * Indicates if this feature is preferred.
+     * </p>
+     * 
+     * @return <code>true</code> if preferred, <code>false</code> otherwise.
+     */
+    public boolean isPreferred() {
+        return preferred;
+    }
+
+    /**
+     * <p>
+     * Indicates if this feature is hidden.
+     * </p>
+     * 
+     * @return <code>true</code> if hidden, <code>false</code> otherwise.
+     */
+    public boolean isHidden() {
+        return hidden;
+    }
+
+    /**
+     * <p>
+     * Indicates if this feature is an expert feature.
+     * </p>
+     * 
+     * @return <code>true</code> if hidden, <code>false</code> otherwise.
+     */
+    public boolean isExpert() {
+        return expert;
+    }
+}
diff --git a/awt/java/beans/IndexedPropertyChangeEvent.java b/awt/java/beans/IndexedPropertyChangeEvent.java
new file mode 100644
index 0000000..c9084c6
--- /dev/null
+++ b/awt/java/beans/IndexedPropertyChangeEvent.java
@@ -0,0 +1,66 @@
+/*
+ * 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 java.beans;
+
+/**
+ * A type of {@link PropertyChangeEvent} that indicates that an indexed property
+ * has changed.
+ * 
+ * @since 1.5
+ */
+public class IndexedPropertyChangeEvent extends PropertyChangeEvent {
+
+    private static final long serialVersionUID = -320227448495806870L;
+
+    private final int index;
+
+    /**
+     * Creates a new property changed event with an indication of the property
+     * index.
+     * 
+     * @param source
+     *            the changed bean.
+     * @param propertyName
+     *            the changed property, or <code>null</code> to indicate an
+     *            unspecified set of the properties have changed.
+     * @param oldValue
+     *            the previous value of the property, or <code>null</code> if
+     *            the <code>propertyName</code> is <code>null</code> or the
+     *            previous value is unknown.
+     * @param newValue
+     *            the new value of the property, or <code>null</code> if the
+     *            <code>propertyName</code> is <code>null</code> or the new
+     *            value is unknown..
+     * @param index
+     *            the index of the property.
+     */
+    public IndexedPropertyChangeEvent(Object source, String propertyName,
+            Object oldValue, Object newValue, int index) {
+        super(source, propertyName, oldValue, newValue);
+        this.index = index;
+    }
+
+    /**
+     * Answer the index of the property that was changed in this event.
+     * 
+     * @return The property element index.
+     */
+    public int getIndex() {
+        return index;
+    }
+}
diff --git a/awt/java/beans/IndexedPropertyDescriptor.java b/awt/java/beans/IndexedPropertyDescriptor.java
new file mode 100644
index 0000000..25667d9
--- /dev/null
+++ b/awt/java/beans/IndexedPropertyDescriptor.java
@@ -0,0 +1,227 @@
+/*
+ *  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 java.beans;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import org.apache.harmony.beans.internal.nls.Messages;
+
+public class IndexedPropertyDescriptor extends PropertyDescriptor {
+    private Method indexedGetter;
+
+    private Method indexedSetter;
+
+    public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass,
+            String getterName, String setterName, String indexedGetterName,
+            String indexedSetterName) throws IntrospectionException {
+        super(propertyName, beanClass, getterName, setterName);
+
+        // RI behaves like this
+        if (indexedGetterName == null && indexedSetterName == null &&
+                (getterName != null || setterName != null)) {
+            throw new IntrospectionException(Messages.getString("beans.50"));
+        }
+        setIndexedReadMethod(beanClass, indexedGetterName);
+        setIndexedWriteMethod(beanClass, indexedSetterName);
+    }
+
+    public IndexedPropertyDescriptor(String propertyName, Method getter, Method setter,
+            Method indexedGetter, Method indexedSetter) throws IntrospectionException {
+        super(propertyName, getter, setter);
+        
+        // we need this in order to be compatible with RI
+        if (indexedGetter == null && indexedSetter == null &&
+                (getter != null || setter != null)) {
+            throw new IntrospectionException(Messages.getString("beans.50"));
+        }
+        setIndexedReadMethod(indexedGetter);
+        setIndexedWriteMethod(indexedSetter);
+    }
+
+    public IndexedPropertyDescriptor(String propertyName, Class<?> beanClass)
+            throws IntrospectionException {
+        super(propertyName, beanClass, null, null);
+        String getterName;
+        String setterName;
+        String indexedGetterName;
+        String indexedSetterName;
+
+        // array getter
+        getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
+        if (hasMethod(beanClass, getterName)) {
+            setReadMethod(beanClass, getterName);
+        }
+        // array setter
+        setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
+        if (hasMethod(beanClass, setterName)) {
+            setWriteMethod(beanClass, setterName);
+        }
+        // indexed getter
+        indexedGetterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
+        if (hasMethod(beanClass, indexedGetterName)) {
+            setIndexedReadMethod(beanClass, indexedGetterName);
+        }
+        // indexed setter
+        indexedSetterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
+        if (hasMethod(beanClass, indexedSetterName)) {
+            setIndexedWriteMethod(beanClass, indexedSetterName);
+        }
+        // RI seems to behave a bit differently
+        if (indexedGetter == null && indexedSetter == null &&
+                getReadMethod() == null && getWriteMethod() == null) {
+            throw new IntrospectionException(
+                    Messages.getString("beans.01", propertyName)); //$NON-NLS-1$
+        }
+        if (indexedGetter == null && indexedSetter == null) {
+            // not an indexed property indeed
+            throw new IntrospectionException(Messages.getString("beans.50"));
+        }
+    }
+
+    public void setIndexedReadMethod(Method indexedGetter) throws IntrospectionException {
+        if (indexedGetter != null) {
+            int modifiers = indexedGetter.getModifiers();
+            Class<?>[] parameterTypes;
+            Class<?> returnType;
+            Class<?> indexedPropertyType;
+
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.21")); //$NON-NLS-1$
+            }
+            parameterTypes = indexedGetter.getParameterTypes();
+            if (parameterTypes.length != 1) {
+                throw new IntrospectionException(Messages.getString("beans.22")); //$NON-NLS-1$
+            }
+            if (!parameterTypes[0].equals(int.class)) {
+                throw new IntrospectionException(Messages.getString("beans.23")); //$NON-NLS-1$
+            }
+            returnType = indexedGetter.getReturnType();
+            indexedPropertyType = getIndexedPropertyType();
+            if ((indexedPropertyType != null) && !returnType.equals(indexedPropertyType)) {
+                throw new IntrospectionException(Messages.getString("beans.24")); //$NON-NLS-1$
+            }
+        }
+        this.indexedGetter = indexedGetter;
+    }
+
+    public void setIndexedWriteMethod(Method indexedSetter) throws IntrospectionException {
+        if (indexedSetter != null) {
+            int modifiers = indexedSetter.getModifiers();
+            Class<?>[] parameterTypes;
+            Class<?> firstParameterType;
+            Class<?> secondParameterType;
+            Class<?> propType;
+
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.25")); //$NON-NLS-1$
+            }
+            parameterTypes = indexedSetter.getParameterTypes();
+            if (parameterTypes.length != 2) {
+                throw new IntrospectionException(Messages.getString("beans.26")); //$NON-NLS-1$
+            }
+            firstParameterType = parameterTypes[0];
+            if (!firstParameterType.equals(int.class)) {
+                throw new IntrospectionException(Messages.getString("beans.27")); //$NON-NLS-1$
+            }
+            secondParameterType = parameterTypes[1];
+            propType = getIndexedPropertyType();
+            if (propType != null && !secondParameterType.equals(propType)) {
+                throw new IntrospectionException(Messages.getString("beans.28")); //$NON-NLS-1$
+            }
+        }
+        this.indexedSetter = indexedSetter;
+    }
+
+    public Method getIndexedWriteMethod() {
+        return indexedSetter;
+    }
+
+    public Method getIndexedReadMethod() {
+        return indexedGetter;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        boolean result = super.equals(obj);
+        
+        if (result) {
+            IndexedPropertyDescriptor pd = (IndexedPropertyDescriptor) obj;
+    
+            if (indexedGetter != null) {
+                result = indexedGetter.equals(pd.getIndexedReadMethod());
+            } else if (result && indexedGetter == null) {
+                result = pd.getIndexedReadMethod() == null;
+            }
+                
+            if (result) {
+                if (indexedSetter != null) {
+                    result = indexedSetter.equals(pd.getIndexedWriteMethod());
+                } else if (indexedSetter == null) {
+                    result = pd.getIndexedWriteMethod() == null;
+                }
+            }
+        }
+            
+        return result;
+    }
+
+    public Class<?> getIndexedPropertyType() {
+        Class<?> result = null;
+
+        if (indexedGetter != null) {
+            result = indexedGetter.getReturnType();
+        } else if (indexedSetter != null) {
+            Class<?>[] parameterTypes = indexedSetter.getParameterTypes();
+
+            result = parameterTypes[1];
+        }
+        return result;
+    }
+
+    private void setIndexedReadMethod(Class<?> beanClass, String indexedGetterName) {
+        Method[] getters = findMethods(beanClass, indexedGetterName);
+        boolean result = false;
+
+        for (Method element : getters) {
+            try {
+                setIndexedReadMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {}
+
+            if (result) {
+                break;
+            }
+        }
+    }
+
+    private void setIndexedWriteMethod(Class<?> beanClass, String indexedSetterName) {
+        Method[] setters = findMethods(beanClass, indexedSetterName);
+        boolean result = false;
+
+        for (Method element : setters) {
+            try {
+                setIndexedWriteMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {}
+
+            if (result) {
+                break;
+            }
+        }
+    }
+}
diff --git a/awt/java/beans/IntrospectionException.java b/awt/java/beans/IntrospectionException.java
new file mode 100644
index 0000000..c895afe
--- /dev/null
+++ b/awt/java/beans/IntrospectionException.java
@@ -0,0 +1,27 @@
+/*
+ *  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 java.beans;
+
+public class IntrospectionException extends Exception {
+
+    static final long serialVersionUID = -3728150539969542619L;
+
+    public IntrospectionException(String message) {
+        super(message);
+    }
+}
diff --git a/awt/java/beans/PropertyChangeEvent.java b/awt/java/beans/PropertyChangeEvent.java
new file mode 100644
index 0000000..97c703a
--- /dev/null
+++ b/awt/java/beans/PropertyChangeEvent.java
@@ -0,0 +1,62 @@
+/*
+ *  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 java.beans;
+
+import java.util.EventObject;
+
+public class PropertyChangeEvent extends EventObject {
+
+    private static final long serialVersionUID = 7042693688939648123L;
+
+    String propertyName;
+
+    Object oldValue;
+
+    Object newValue;
+
+    Object propagationId;
+
+    public PropertyChangeEvent(Object source, String propertyName,
+            Object oldValue, Object newValue) {
+        super(source);
+
+        this.propertyName = propertyName;
+        this.oldValue = oldValue;
+        this.newValue = newValue;
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void setPropagationId(Object propagationId) {
+        this.propagationId = propagationId;
+    }
+
+    public Object getPropagationId() {
+        return propagationId;
+    }
+
+    public Object getOldValue() {
+        return oldValue;
+    }
+
+    public Object getNewValue() {
+        return newValue;
+    }
+}
diff --git a/awt/java/beans/PropertyChangeListener.java b/awt/java/beans/PropertyChangeListener.java
new file mode 100644
index 0000000..94422c0
--- /dev/null
+++ b/awt/java/beans/PropertyChangeListener.java
@@ -0,0 +1,25 @@
+/*
+ *  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 java.beans;
+
+import java.util.EventListener;
+
+public interface PropertyChangeListener extends EventListener {
+
+    public void propertyChange(PropertyChangeEvent event);
+}
diff --git a/awt/java/beans/PropertyChangeListenerProxy.java b/awt/java/beans/PropertyChangeListenerProxy.java
new file mode 100644
index 0000000..f4f3aec
--- /dev/null
+++ b/awt/java/beans/PropertyChangeListenerProxy.java
@@ -0,0 +1,41 @@
+/*
+ *  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 java.beans;
+
+import java.util.EventListenerProxy;
+
+public class PropertyChangeListenerProxy extends EventListenerProxy implements
+        PropertyChangeListener {
+
+    String propertyName;
+
+    public PropertyChangeListenerProxy(String propertyName,
+            PropertyChangeListener listener) {
+        super(listener);
+        this.propertyName = propertyName;
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void propertyChange(PropertyChangeEvent event) {
+        PropertyChangeListener listener = (PropertyChangeListener) getListener();
+        listener.propertyChange(event);
+    }
+}
diff --git a/awt/java/beans/PropertyChangeSupport.java b/awt/java/beans/PropertyChangeSupport.java
new file mode 100644
index 0000000..d56e63a
--- /dev/null
+++ b/awt/java/beans/PropertyChangeSupport.java
@@ -0,0 +1,351 @@
+/*
+ *  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 java.beans;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class PropertyChangeSupport implements Serializable {
+
+    private static final long serialVersionUID = 6401253773779951803l;
+
+    private transient Object sourceBean;
+
+    private transient List<PropertyChangeListener> allPropertiesChangeListeners =
+            new ArrayList<PropertyChangeListener>();
+
+    private transient Map<String, List<PropertyChangeListener>>
+            selectedPropertiesChangeListeners =
+            new HashMap<String, List<PropertyChangeListener>>();
+
+    // fields for serialization compatibility
+    private Hashtable<String, List<PropertyChangeListener>> children;
+
+    private Object source;
+
+    private int propertyChangeSupportSerializedDataVersion = 1;
+
+    public PropertyChangeSupport(Object sourceBean) {
+        if (sourceBean == null) {
+            throw new NullPointerException();
+        }
+        this.sourceBean = sourceBean;
+    }
+
+    public void firePropertyChange(String propertyName, Object oldValue,
+            Object newValue) {
+        PropertyChangeEvent event = createPropertyChangeEvent(propertyName,
+                oldValue, newValue);
+        doFirePropertyChange(event);
+    }
+
+    public void fireIndexedPropertyChange(String propertyName, int index,
+            Object oldValue, Object newValue) {
+
+        // nulls and equals check done in doFire...
+        doFirePropertyChange(new IndexedPropertyChangeEvent(sourceBean,
+                propertyName, oldValue, newValue, index));
+    }
+
+    public synchronized void removePropertyChangeListener(String propertyName,
+            PropertyChangeListener listener) {
+        if ((propertyName != null) && (listener != null)) {
+            List<PropertyChangeListener> listeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (listeners != null) {
+                listeners.remove(listener);
+            }
+        }
+    }
+
+    public synchronized void addPropertyChangeListener(String propertyName,
+            PropertyChangeListener listener) {
+        if ((listener != null) && (propertyName != null)) {
+            List<PropertyChangeListener> listeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (listeners == null) {
+                listeners = new ArrayList<PropertyChangeListener>();
+                selectedPropertiesChangeListeners.put(propertyName, listeners);
+            }
+
+            // RI compatibility
+            if (listener instanceof PropertyChangeListenerProxy) {
+                PropertyChangeListenerProxy proxy =
+                        (PropertyChangeListenerProxy) listener;
+
+                listeners.add(new PropertyChangeListenerProxy(
+                        proxy.getPropertyName(),
+                        (PropertyChangeListener) proxy.getListener()));
+            } else {
+                listeners.add(listener);
+            }
+        }
+    }
+
+    public synchronized PropertyChangeListener[] getPropertyChangeListeners(
+            String propertyName) {
+        List<PropertyChangeListener> listeners = null;
+
+        if (propertyName != null) {
+            listeners = selectedPropertiesChangeListeners.get(propertyName);
+        }
+
+        return (listeners == null) ? new PropertyChangeListener[] {}
+                : listeners.toArray(
+                        new PropertyChangeListener[listeners.size()]);
+    }
+
+    public void firePropertyChange(String propertyName, boolean oldValue,
+            boolean newValue) {
+        PropertyChangeEvent event = createPropertyChangeEvent(propertyName,
+                oldValue, newValue);
+        doFirePropertyChange(event);
+    }
+
+    public void fireIndexedPropertyChange(String propertyName, int index,
+            boolean oldValue, boolean newValue) {
+
+        if (oldValue != newValue) {
+            fireIndexedPropertyChange(propertyName, index, Boolean
+                    .valueOf(oldValue), Boolean.valueOf(newValue));
+        }
+    }
+
+    public void firePropertyChange(String propertyName, int oldValue,
+            int newValue) {
+        PropertyChangeEvent event = createPropertyChangeEvent(propertyName,
+                oldValue, newValue);
+        doFirePropertyChange(event);
+    }
+
+    public void fireIndexedPropertyChange(String propertyName, int index,
+            int oldValue, int newValue) {
+
+        if (oldValue != newValue) {
+            fireIndexedPropertyChange(propertyName, index,
+                    new Integer(oldValue), new Integer(newValue));
+        }
+    }
+
+    public synchronized boolean hasListeners(String propertyName) {
+        boolean result = allPropertiesChangeListeners.size() > 0;
+        if (!result && (propertyName != null)) {
+            List<PropertyChangeListener> listeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+            if (listeners != null) {
+                result = listeners.size() > 0;
+            }
+        }
+        return result;
+    }
+
+    public synchronized void removePropertyChangeListener(
+            PropertyChangeListener listener) {
+        if (listener != null) {
+            if (listener instanceof PropertyChangeListenerProxy) {
+                String name = ((PropertyChangeListenerProxy) listener)
+                        .getPropertyName();
+                PropertyChangeListener lst = (PropertyChangeListener)
+                        ((PropertyChangeListenerProxy) listener).getListener();
+
+                removePropertyChangeListener(name, lst);
+            } else {
+                allPropertiesChangeListeners.remove(listener);
+            }
+        }
+    }
+
+    public synchronized void addPropertyChangeListener(
+            PropertyChangeListener listener) {
+        if (listener != null) {
+            if (listener instanceof PropertyChangeListenerProxy) {
+                String name = ((PropertyChangeListenerProxy) listener)
+                        .getPropertyName();
+                PropertyChangeListener lst = (PropertyChangeListener)
+                        ((PropertyChangeListenerProxy) listener).getListener();
+                addPropertyChangeListener(name, lst);
+            } else {
+                allPropertiesChangeListeners.add(listener);
+            }
+        }
+    }
+
+    public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
+        ArrayList<PropertyChangeListener> result =
+                new ArrayList<PropertyChangeListener>(
+                        allPropertiesChangeListeners);
+
+        for (String propertyName : selectedPropertiesChangeListeners.keySet()) {
+            List<PropertyChangeListener> selectedListeners =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (selectedListeners != null) {
+
+                for (PropertyChangeListener listener : selectedListeners) {
+                    result.add(new PropertyChangeListenerProxy(propertyName,
+                            listener));
+                }
+            }
+        }
+
+        return result.toArray(new PropertyChangeListener[result.size()]);
+    }
+
+    private void writeObject(ObjectOutputStream oos) throws IOException {
+        List<PropertyChangeListener> allSerializedPropertiesChangeListeners =
+                new ArrayList<PropertyChangeListener>();
+
+        for (PropertyChangeListener pcl : allPropertiesChangeListeners) {
+            if (pcl instanceof Serializable) {
+                allSerializedPropertiesChangeListeners.add(pcl);
+            }
+        }
+
+        Map<String, List<PropertyChangeListener>>
+                selectedSerializedPropertiesChangeListeners =
+                        new HashMap<String, List<PropertyChangeListener>>();
+
+        for (String propertyName : selectedPropertiesChangeListeners.keySet()) {
+            List<PropertyChangeListener> keyValues =
+                    selectedPropertiesChangeListeners.get(propertyName);
+
+            if (keyValues != null) {
+                List<PropertyChangeListener> serializedPropertiesChangeListeners
+                        = new ArrayList<PropertyChangeListener>();
+
+                for (PropertyChangeListener pcl : keyValues) {
+                    if (pcl instanceof Serializable) {
+                        serializedPropertiesChangeListeners.add(pcl);
+                    }
+                }
+
+                if (!serializedPropertiesChangeListeners.isEmpty()) {
+                    selectedSerializedPropertiesChangeListeners.put(
+                            propertyName, serializedPropertiesChangeListeners);
+                }
+            }
+        }
+
+        children = new Hashtable<String, List<PropertyChangeListener>>(
+                selectedSerializedPropertiesChangeListeners);
+        children.put("", allSerializedPropertiesChangeListeners); //$NON-NLS-1$
+        oos.writeObject(children);
+
+        Object source = null;
+        if (sourceBean instanceof Serializable) {
+            source = sourceBean;
+        }
+        oos.writeObject(source);
+
+        oos.writeInt(propertyChangeSupportSerializedDataVersion);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream ois) throws IOException,
+            ClassNotFoundException {
+        children = (Hashtable<String, List<PropertyChangeListener>>) ois
+                .readObject();
+
+        selectedPropertiesChangeListeners = new HashMap<String, List<PropertyChangeListener>>(
+                children);
+        allPropertiesChangeListeners = selectedPropertiesChangeListeners
+                .remove(""); //$NON-NLS-1$
+        if (allPropertiesChangeListeners == null) {
+            allPropertiesChangeListeners = new ArrayList<PropertyChangeListener>();
+        }
+
+        sourceBean = ois.readObject();
+        propertyChangeSupportSerializedDataVersion = ois.readInt();
+    }
+
+    public void firePropertyChange(PropertyChangeEvent event) {
+        doFirePropertyChange(event);
+    }
+
+    private PropertyChangeEvent createPropertyChangeEvent(String propertyName,
+            Object oldValue, Object newValue) {
+        return new PropertyChangeEvent(sourceBean, propertyName, oldValue,
+                newValue);
+    }
+
+    private PropertyChangeEvent createPropertyChangeEvent(String propertyName,
+            boolean oldValue, boolean newValue) {
+        return new PropertyChangeEvent(sourceBean, propertyName, oldValue,
+                newValue);
+    }
+
+    private PropertyChangeEvent createPropertyChangeEvent(String propertyName,
+            int oldValue, int newValue) {
+        return new PropertyChangeEvent(sourceBean, propertyName, oldValue,
+                newValue);
+    }
+
+    private void doFirePropertyChange(PropertyChangeEvent event) {
+        String propertyName = event.getPropertyName();
+        Object oldValue = event.getOldValue();
+        Object newValue = event.getNewValue();
+
+        if ((newValue != null) && (oldValue != null)
+                && newValue.equals(oldValue)) {
+            return;
+        }
+
+        /*
+         * Copy the listeners collections so they can be modified while we fire
+         * events.
+         */
+
+        // Listeners to all property change events
+        PropertyChangeListener[] listensToAll;
+        // Listens to a given property change
+        PropertyChangeListener[] listensToOne = null;
+        synchronized (this) {
+            listensToAll = allPropertiesChangeListeners
+                    .toArray(new PropertyChangeListener[allPropertiesChangeListeners
+                            .size()]);
+
+            List<PropertyChangeListener> listeners = selectedPropertiesChangeListeners
+                    .get(propertyName);
+            if (listeners != null) {
+                listensToOne = listeners
+                        .toArray(new PropertyChangeListener[listeners.size()]);
+            }
+        }
+
+        // Fire the listeners
+        for (PropertyChangeListener listener : listensToAll) {
+            listener.propertyChange(event);
+        }
+        if (listensToOne != null) {
+            for (PropertyChangeListener listener : listensToOne) {
+                listener.propertyChange(event);
+            }
+        }
+    }
+
+}
diff --git a/awt/java/beans/PropertyDescriptor.java b/awt/java/beans/PropertyDescriptor.java
new file mode 100644
index 0000000..9389152
--- /dev/null
+++ b/awt/java/beans/PropertyDescriptor.java
@@ -0,0 +1,300 @@
+/*
+ *  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 java.beans;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Vector;
+import org.apache.harmony.beans.internal.nls.Messages;
+
+public class PropertyDescriptor extends FeatureDescriptor {
+    private Method getter;
+
+    private Method setter;
+
+    private Class<?> propertyEditorClass;
+
+    private boolean constrained;
+
+    private boolean bound;
+
+    public PropertyDescriptor(String propertyName, Class<?> beanClass, String getterName,
+            String setterName) throws IntrospectionException {
+        super();
+        if (beanClass == null) {
+            throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$
+        }
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
+        }
+        this.setName(propertyName);
+        this.setDisplayName(propertyName);
+        if (setterName != null) {
+            if (hasMethod(beanClass, setterName)) {
+                setWriteMethod(beanClass, setterName);
+            } else {
+                throw new IntrospectionException(Messages.getString("beans.20")); //$NON-NLS-1$
+            }
+        }
+        if (getterName != null) {
+            if (hasMethod(beanClass, getterName)) {
+                setReadMethod(beanClass, getterName);
+            } else {
+                throw new IntrospectionException(Messages.getString("beans.1F")); //$NON-NLS-1$
+            }
+        }
+    }
+
+    public PropertyDescriptor(String propertyName, Method getter, Method setter)
+            throws IntrospectionException {
+        super();
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
+        }
+        this.setName(propertyName);
+        this.setDisplayName(propertyName);
+        setWriteMethod(setter);
+        setReadMethod(getter);
+    }
+
+    public PropertyDescriptor(String propertyName, Class<?> beanClass)
+            throws IntrospectionException {
+        String getterName;
+        String setterName;
+        if (beanClass == null) {
+            throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$
+        }
+        if (propertyName == null || propertyName.length() == 0) {
+            throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
+        }
+        this.setName(propertyName);
+        this.setDisplayName(propertyName);
+        getterName = createDefaultMethodName(propertyName, "is"); //$NON-NLS-1$
+        if (hasMethod(beanClass, getterName)) {
+            setReadMethod(beanClass, getterName);
+        } else {
+            getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
+            if (hasMethod(beanClass, getterName)) {
+                setReadMethod(beanClass, getterName);
+            }
+        }
+        setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
+        if (hasMethod(beanClass, setterName)) {
+            setWriteMethod(beanClass, setterName);
+        }
+        if (getter == null && setter == null) {
+            throw new IntrospectionException(Messages.getString("beans.01", propertyName)); //$NON-NLS-1$
+        }
+    }
+
+    public void setWriteMethod(Method setter) throws IntrospectionException {
+        if (setter != null) {
+            int modifiers = setter.getModifiers();
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.05")); //$NON-NLS-1$
+            }
+            Class<?>[] parameterTypes = setter.getParameterTypes();
+            if (parameterTypes.length != 1) {
+                throw new IntrospectionException(Messages.getString("beans.06")); //$NON-NLS-1$
+            }
+            Class<?> parameterType = parameterTypes[0];
+            Class<?> propertyType = getPropertyType();
+            if (propertyType != null && !propertyType.equals(parameterType)) {
+                throw new IntrospectionException(Messages.getString("beans.07")); //$NON-NLS-1$
+            }
+        }
+        this.setter = setter;
+    }
+
+    public void setReadMethod(Method getter) throws IntrospectionException {
+        if (getter != null) {
+            int modifiers = getter.getModifiers();
+            if (!Modifier.isPublic(modifiers)) {
+                throw new IntrospectionException(Messages.getString("beans.0A")); //$NON-NLS-1$
+            }
+            Class<?>[] parameterTypes = getter.getParameterTypes();
+            if (parameterTypes.length != 0) {
+                throw new IntrospectionException(Messages.getString("beans.08")); //$NON-NLS-1$
+            }
+            Class<?> returnType = getter.getReturnType();
+            if (returnType.equals(Void.TYPE)) {
+                throw new IntrospectionException(Messages.getString("beans.33")); //$NON-NLS-1$
+            }
+            Class<?> propertyType = getPropertyType();
+            if ((propertyType != null) && !returnType.equals(propertyType)) {
+                throw new IntrospectionException(Messages.getString("beans.09")); //$NON-NLS-1$
+            }
+        }
+        this.getter = getter;
+    }
+
+    public Method getWriteMethod() {
+        return setter;
+    }
+
+    public Method getReadMethod() {
+        return getter;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        boolean result = (object != null && object instanceof PropertyDescriptor);
+        if (result) {
+            PropertyDescriptor pd = (PropertyDescriptor) object;
+            boolean gettersAreEqual = (this.getter == null) && (pd.getReadMethod() == null)
+                    || (this.getter != null) && (this.getter.equals(pd.getReadMethod()));
+            boolean settersAreEqual = (this.setter == null) && (pd.getWriteMethod() == null)
+                    || (this.setter != null) && (this.setter.equals(pd.getWriteMethod()));
+            boolean propertyTypesAreEqual = this.getPropertyType() == pd.getPropertyType();
+            boolean propertyEditorClassesAreEqual = this.getPropertyEditorClass() == pd
+                    .getPropertyEditorClass();
+            boolean boundPropertyAreEqual = this.isBound() == pd.isBound();
+            boolean constrainedPropertyAreEqual = this.isConstrained() == pd.isConstrained();
+            result = gettersAreEqual && settersAreEqual && propertyTypesAreEqual
+                    && propertyEditorClassesAreEqual && boundPropertyAreEqual
+                    && constrainedPropertyAreEqual;
+        }
+        return result;
+    }
+
+    public void setPropertyEditorClass(Class<?> propertyEditorClass) {
+        this.propertyEditorClass = propertyEditorClass;
+    }
+
+    public Class<?> getPropertyType() {
+        Class<?> result = null;
+        if (getter != null) {
+            result = getter.getReturnType();
+        } else if (setter != null) {
+            Class<?>[] parameterTypes = setter.getParameterTypes();
+            result = parameterTypes[0];
+        }
+        return result;
+    }
+
+    public Class<?> getPropertyEditorClass() {
+        return propertyEditorClass;
+    }
+
+    public void setConstrained(boolean constrained) {
+        this.constrained = constrained;
+    }
+
+    public void setBound(boolean bound) {
+        this.bound = bound;
+    }
+
+    public boolean isConstrained() {
+        return constrained;
+    }
+
+    public boolean isBound() {
+        return bound;
+    }
+
+    boolean hasMethod(Class<?> beanClass, String methodName) {
+        Method[] methods = findMethods(beanClass, methodName);
+        return (methods.length > 0);
+    }
+
+    String createDefaultMethodName(String propertyName, String prefix) {
+        String result = null;
+        if (propertyName != null) {
+            String bos = propertyName.substring(0, 1).toUpperCase();
+            String eos = propertyName.substring(1, propertyName.length());
+            result = prefix + bos + eos;
+        }
+        return result;
+    }
+
+    Method[] findMethods(Class<?> aClass, String methodName) {
+        Method[] allMethods = aClass.getMethods();
+        Vector<Method> matchedMethods = new Vector<Method>();
+        Method[] result;
+        for (Method method : allMethods) {
+            if (method.getName().equals(methodName)) {
+                matchedMethods.add(method);
+            }
+        }
+        result = new Method[matchedMethods.size()];
+        for (int j = 0; j < matchedMethods.size(); ++j) {
+            result[j] = matchedMethods.elementAt(j);
+        }
+        return result;
+    }
+
+    void setReadMethod(Class<?> beanClass, String getterName) {
+        boolean result = false;
+        Method[] getters = findMethods(beanClass, getterName);
+        for (Method element : getters) {
+            try {
+                setReadMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {
+            }
+            if (result) {
+                break;
+            }
+        }
+    }
+
+    void setWriteMethod(Class<?> beanClass, String setterName) throws IntrospectionException {
+        boolean result = false;
+        Method[] setters = findMethods(beanClass, setterName);
+        for (Method element : setters) {
+            try {
+                setWriteMethod(element);
+                result = true;
+            } catch (IntrospectionException ie) {
+            }
+            if (result) {
+                break;
+            }
+        }
+    }
+
+    public PropertyEditor createPropertyEditor(Object bean) {
+        PropertyEditor editor;
+        if (propertyEditorClass == null) {
+            return null;
+        }
+        if (!PropertyEditor.class.isAssignableFrom(propertyEditorClass)) {
+            // beans.48=Property editor is not assignable from the
+            // PropertyEditor interface
+            throw new ClassCastException(Messages.getString("beans.48")); //$NON-NLS-1$
+        }
+        try {
+            Constructor<?> constr;
+            try {
+                // try to look for the constructor with single Object argument
+                constr = propertyEditorClass.getConstructor(Object.class);
+                editor = (PropertyEditor) constr.newInstance(bean);
+            } catch (NoSuchMethodException e) {
+                // try no-argument constructor
+                constr = propertyEditorClass.getConstructor();
+                editor = (PropertyEditor) constr.newInstance();
+            }
+        } catch (Exception e) {
+            // beans.47=Unable to instantiate property editor
+            RuntimeException re = new RuntimeException(Messages.getString("beans.47"), e); //$NON-NLS-1$
+            throw re;
+        }
+        return editor;
+    }
+}
diff --git a/awt/java/beans/PropertyEditor.java b/awt/java/beans/PropertyEditor.java
new file mode 100644
index 0000000..65bedea
--- /dev/null
+++ b/awt/java/beans/PropertyEditor.java
@@ -0,0 +1,49 @@
+/*
+ *  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 java.beans;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+
+public interface PropertyEditor {
+
+    public void paintValue(Graphics gfx, Rectangle box);
+
+    public void setAsText(String text) throws IllegalArgumentException;
+
+    public String[] getTags();
+
+    public String getJavaInitializationString();
+
+    public String getAsText();
+
+    public void setValue(Object value);
+
+    public Object getValue();
+
+    public void removePropertyChangeListener(PropertyChangeListener listener);
+
+    public void addPropertyChangeListener(PropertyChangeListener listener);
+
+    public Component getCustomEditor();
+
+    public boolean supportsCustomEditor();
+
+    public boolean isPaintable();
+}
diff --git a/awt/java/beans/PropertyEditorManager.java b/awt/java/beans/PropertyEditorManager.java
new file mode 100644
index 0000000..ed55829
--- /dev/null
+++ b/awt/java/beans/PropertyEditorManager.java
@@ -0,0 +1,114 @@
+/*
+ *  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 java.beans;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PropertyEditorManager {
+
+    private static String[] path = { "org.apache.harmony.beans.editors" }; //$NON-NLS-1$
+
+    private static final Map<Class<?>, Class<?>> registeredEditors = new HashMap<Class<?>, Class<?>>();
+
+    public PropertyEditorManager() {
+    }
+
+    public static void registerEditor(Class<?> targetType, Class<?> editorClass) {
+        if (targetType == null) {
+            throw new NullPointerException();
+        }
+
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertiesAccess();
+        }
+        if (editorClass != null) {
+            registeredEditors.put(targetType, editorClass);
+        } else {
+            registeredEditors.remove(targetType);
+        }
+    }
+
+    public static synchronized PropertyEditor findEditor(Class<?> targetType) {
+        if (targetType == null) {
+            throw new NullPointerException();
+        }
+
+        Class<?> editorClass = null;
+        PropertyEditor editor = null;
+
+        editorClass = registeredEditors.get(targetType);
+
+        if (editorClass == null) {
+            String editorClassName = targetType.getName() + "Editor"; //$NON-NLS-1$
+            ClassLoader loader = targetType.getClassLoader();
+
+            if (loader == null) {
+                loader = Thread.currentThread().getContextClassLoader();
+            }
+
+            try {
+                editorClass = Class.forName(editorClassName, true, loader);
+            } catch (ClassNotFoundException cnfe) {
+                String shortEditorClassName = editorClassName
+                        .substring(editorClassName.lastIndexOf(".") + 1); //$NON-NLS-1$
+
+                if (targetType.isPrimitive()) {
+                    shortEditorClassName = shortEditorClassName.substring(0, 1)
+                            .toUpperCase()
+                            + shortEditorClassName.substring(1);
+                }
+
+                for (String element : path) {
+                    editorClassName = element + "." + shortEditorClassName; //$NON-NLS-1$
+
+                    try {
+                        editorClass = Class.forName(editorClassName, true,
+                                loader);
+                        break;
+                    } catch (Exception e) {
+                    }
+                }
+            } catch (Exception e) {
+            }
+        }
+
+        if (editorClass != null) {
+            try {
+                editor = (PropertyEditor) editorClass.newInstance();
+            } catch (Exception e) {
+            }
+        }
+
+        return editor;
+    }
+
+    public static synchronized void setEditorSearchPath(String[] apath) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPropertiesAccess();
+        }
+
+        path = apath;
+    }
+
+    public static synchronized String[] getEditorSearchPath() {
+        return path;
+    }
+}
diff --git a/awt/java/beans/PropertyEditorSupport.java b/awt/java/beans/PropertyEditorSupport.java
new file mode 100644
index 0000000..c3929a1
--- /dev/null
+++ b/awt/java/beans/PropertyEditorSupport.java
@@ -0,0 +1,129 @@
+/*
+ *  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 java.beans;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.harmony.beans.internal.nls.Messages;
+
+public class PropertyEditorSupport implements PropertyEditor {
+
+    Object source = null;
+
+    List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
+
+    Object oldValue = null;
+
+    Object newValue = null;
+
+    public PropertyEditorSupport(Object source) {
+        if (source == null) {
+            throw new NullPointerException(Messages.getString("beans.0C")); //$NON-NLS-1$
+        }
+        this.source = source;
+    }
+
+    public PropertyEditorSupport() {
+        source = this;
+    }
+
+    public void paintValue(Graphics gfx, Rectangle box) {
+    }
+
+    public void setAsText(String text) throws IllegalArgumentException {
+        if (newValue instanceof String) {
+            setValue(text);
+        } else {
+            throw new IllegalArgumentException(text);
+        }
+    }
+
+    public String[] getTags() {
+        return null;
+    }
+
+    public String getJavaInitializationString() {
+        return "???"; //$NON-NLS-1$
+    }
+
+    public String getAsText() {
+        return newValue == null ? "null" : newValue.toString(); //$NON-NLS-1$
+    }
+
+    public void setValue(Object value) {
+        this.oldValue = this.newValue;
+        this.newValue = value;
+        firePropertyChange();
+    }
+
+    public Object getValue() {
+        return newValue;
+    }
+
+    public void setSource(Object source) {
+        if (source == null) {
+            throw new NullPointerException(Messages.getString("beans.0C")); //$NON-NLS-1$
+        }
+        this.source = source;
+    }
+
+    public Object getSource() {
+        return source;
+    }
+
+    public synchronized void removePropertyChangeListener(
+            PropertyChangeListener listener) {
+        if (listeners != null) {
+            listeners.remove(listener);
+        }
+    }
+
+    public synchronized void addPropertyChangeListener(
+            PropertyChangeListener listener) {
+        listeners.add(listener);
+    }
+
+    public Component getCustomEditor() {
+        return null;
+    }
+
+    public boolean supportsCustomEditor() {
+        return false;
+    }
+
+    public boolean isPaintable() {
+        return false;
+    }
+
+    public void firePropertyChange() {
+        if (listeners.size() > 0) {
+            PropertyChangeEvent event = new PropertyChangeEvent(source, null,
+                    oldValue, newValue);
+            Iterator<PropertyChangeListener> iterator = listeners.iterator();
+
+            while (iterator.hasNext()) {
+                PropertyChangeListener listener = iterator.next();
+                listener.propertyChange(event);
+            }
+        }
+    }
+}
diff --git a/awt/java/beans/PropertyVetoException.java b/awt/java/beans/PropertyVetoException.java
new file mode 100644
index 0000000..c7f092a
--- /dev/null
+++ b/awt/java/beans/PropertyVetoException.java
@@ -0,0 +1,54 @@
+/*
+ *  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 java.beans;
+
+/**
+ * Indicates that a proposed property change is unacceptable.
+ */
+public class PropertyVetoException extends Exception {
+
+    private static final long serialVersionUID = 129596057694162164L;
+
+    private final PropertyChangeEvent evt;
+
+    /**
+     * <p>
+     * Constructs an instance with a message and the change event.
+     * </p>
+     * 
+     * @param message
+     *            A description of the veto.
+     * @param event
+     *            The event that was vetoed.
+     */
+    public PropertyVetoException(String message, PropertyChangeEvent event) {
+        super(message);
+        this.evt = event;
+    }
+
+    /**
+     * <p>
+     * Gets the property change event.
+     * </p>
+     * 
+     * @return An instance of {@link PropertyChangeEvent}
+     */
+    public PropertyChangeEvent getPropertyChangeEvent() {
+        return evt;
+    }
+}
diff --git a/awt/javax/imageio/IIOException.java b/awt/javax/imageio/IIOException.java
new file mode 100644
index 0000000..fbfeb42
--- /dev/null
+++ b/awt/javax/imageio/IIOException.java
@@ -0,0 +1,52 @@
+/*
+ *  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;
+
+import java.io.IOException;
+
+/**
+ * The IIOException class indicates errors in reading/writing operations.
+ */
+public class IIOException extends IOException {
+
+    /** The Constant serialVersionUID. */
+    private static final long serialVersionUID = -3216210718638985251L;
+
+    /**
+     * Instantiates a new IIOException.
+     * 
+     * @param message the detailed message.
+     */
+    public IIOException(String message) {
+        super(message);
+    }
+
+    /**
+     * Instantiates a new IIOException.
+     * 
+     * @param message the detailed message.
+     * @param cause the cause of this exception.
+     */
+    public IIOException(String message, Throwable cause) {
+        super(message);
+        initCause(cause);
+    }
+}
diff --git a/awt/javax/imageio/IIOImage.java b/awt/javax/imageio/IIOImage.java
new file mode 100644
index 0000000..e17a9fc
--- /dev/null
+++ b/awt/javax/imageio/IIOImage.java
@@ -0,0 +1,203 @@
+/*
+ *  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;
+
+import javax.imageio.metadata.IIOMetadata;
+import java.awt.image.RenderedImage;
+import java.awt.image.Raster;
+import java.awt.image.BufferedImage;
+import java.util.List;
+
+/**
+ * The IIOImage class combines the image, image's thumbnail and image's metadata.
+ * The image can be presented as RenderedImage or Raster object.
+ */
+public class IIOImage {
+
+    /** The image of this IIOImage. */
+    protected RenderedImage image;
+    
+    /** The raster of this IIOImage. */
+    protected Raster raster;
+    
+    /** The list with thumbnails associated with the image. */
+    protected List<? extends BufferedImage> thumbnails;
+    
+    /** The metadata associated with the image. */
+    protected IIOMetadata metadata;
+
+    /**
+     * Instantiates a new IIOImage with the specified RenderedImage, 
+     * list of thumbnails and metadata.
+     * 
+     * @param image the image specified by RenderedImage.
+     * @param thumbnails the list of BufferedImage objects which 
+     * represent the thumbnails of the image.
+     * @param metadata the metadata of the image.
+     */
+    public IIOImage(RenderedImage image, List<? extends BufferedImage> thumbnails, IIOMetadata metadata) {
+        if (image == null) {
+            throw new IllegalArgumentException("image should not be NULL");
+        }
+        this.raster = null;
+        this.image = image;
+        this.thumbnails = thumbnails;
+        this.metadata = metadata;
+    }
+
+    /**
+     * Instantiates a new IIOImage with the specified Raster, list of
+     * thumbnails and metadata.
+     * 
+     * @param raster the Raster.
+     * @param thumbnails the list of BufferedImage objects which 
+     * represent the thumbnails of Raster data.
+     * @param metadata the metadata.
+     */
+    public IIOImage(Raster raster, List<? extends BufferedImage> thumbnails, IIOMetadata metadata) {
+        if (raster == null) {
+            throw new IllegalArgumentException("raster should not be NULL");
+        }
+        this.image = null;
+        this.raster = raster;
+        this.thumbnails = thumbnails;
+        this.metadata = metadata;
+    }
+
+    /**
+     * Gets the RenderedImage object or returns null if this IIOImage 
+     * object is associated with a Raster.
+     * 
+     * @return the RenderedImage object or null if this IIOImage 
+     * object is associated with a Raster.
+     */
+    public RenderedImage getRenderedImage() {
+        return image;
+    }
+
+    /**
+     * Sets the RenderedImage to this IIOImage object.
+     * 
+     * @param image the RenderedImage to be set to this IIOImage.
+     */
+    public void setRenderedImage(RenderedImage image) {
+        if (image == null) {
+            throw new IllegalArgumentException("image should not be NULL");
+        }
+        raster = null;
+        this.image = image;
+    }
+
+    /**
+     * Returns true if the IIOImage object associated with a Raster, or 
+     * false if it's associated with a RenderedImage.
+     * 
+     * @return true if the IIOImage object associated with a Raster, or 
+     * false if it's associated with a RenderedImage.
+     */
+    public boolean hasRaster() {
+        return raster != null;
+    }
+
+    /**
+     * Gets the Raster object or returns null if this IIOImage object is
+     * associated with a RenderedImage.
+     * 
+     * @return the Raster or null if this IIOImage object
+     * is associated with a RenderedImage.
+     */
+    public Raster getRaster() {
+        return raster;
+    }
+
+    /**
+     * Sets the Raster to the IIOImage.
+     * 
+     * @param raster the new Raster to the IIOImage.
+     */
+    public void setRaster(Raster raster) {
+        if (raster == null) {
+            throw new IllegalArgumentException("raster should not be NULL");
+        }
+        image = null;
+        this.raster = raster;
+    }
+
+    /**
+     * Gets the number of thumbnails for this IIOImage.
+     * 
+     * @return the number of thumbnails for this IIOImage.
+     */
+    public int getNumThumbnails() {
+        return thumbnails != null ? thumbnails.size() : 0;
+    }
+
+    /**
+     * Gets the thumbnail with the specified index in the list.
+     * 
+     * @param index the index of the thumbnail in the list.
+     * 
+     * @return the thumbnail with the specified index in the list.
+     */
+    public BufferedImage getThumbnail(int index) {
+        if (thumbnails != null) {
+            return thumbnails.get(index);
+        }
+        throw new IndexOutOfBoundsException("no thumbnails were set");
+    }
+
+    /**
+     * Gets the list of thumbnails.
+     * 
+     * @return the list of thumbnails.
+     */
+    public List<? extends BufferedImage> getThumbnails() {
+        return thumbnails;
+    }
+
+    /**
+     * Sets the list of thumbnails images to this IIOImage object.
+     * 
+     * @param thumbnails the list of BufferedImage which represent
+     * thumbnails.
+     */
+    public void setThumbnails(List<? extends BufferedImage> thumbnails) {
+        this.thumbnails = thumbnails;
+    }
+
+    /**
+     * Gets the metadata of this IIOImage.
+     * 
+     * @return the metadata of this IIOImage.
+     */
+    public IIOMetadata getMetadata() {
+        return metadata;
+    }
+
+    /**
+     * Sets the metadata to this IIOImage object.
+     * 
+     * @param metadata the IIOMetadata, or null.
+     */
+    public void setMetadata(IIOMetadata metadata) {
+        this.metadata = metadata;
+    }
+}
diff --git a/awt/javax/imageio/IIOParam.java b/awt/javax/imageio/IIOParam.java
new file mode 100644
index 0000000..d998b6e
--- /dev/null
+++ b/awt/javax/imageio/IIOParam.java
@@ -0,0 +1,316 @@
+/*
+ *  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;
+
+import java.awt.*;
+
+/**
+ * The IIOParam abstract class is superclass for     
+ * ImageReadParam and ImageWriteParam classes and provides 
+ * methods and variables which they share.
+ */
+public abstract class IIOParam {
+    
+    /** The source region. */
+    protected Rectangle sourceRegion;
+    
+    /** The source x subsampling. */
+    protected int sourceXSubsampling = 1;
+    
+    /** The source y subsampling. */
+    protected int sourceYSubsampling = 1;
+    
+    /** The subsampling x offset. */
+    protected int subsamplingXOffset;
+    
+    /** The subsampling y offset. */
+    protected int subsamplingYOffset;
+    
+    /** The source bands. */
+    protected int[] sourceBands;
+    
+    /** The destination type. */
+    protected ImageTypeSpecifier destinationType;
+    
+    /** The destination offset. */
+    protected Point destinationOffset = new Point(0, 0);
+    
+    /** The default controller. */
+    protected IIOParamController defaultController;
+    
+    /** The controller. */
+    protected IIOParamController controller;
+
+    /**
+     * Instantiates a new IIOParam.
+     */
+    protected IIOParam() {}
+
+    /**
+     * Sets the source region as a Rectangle object.
+     * 
+     * @param sourceRegion the Rectangle which specifies the source region.
+     */
+    public void setSourceRegion(Rectangle sourceRegion) {
+        if (sourceRegion != null) {
+            if (sourceRegion.x < 0) {
+                throw new IllegalArgumentException("x < 0");
+            }
+            if (sourceRegion.y < 0) {
+                throw new IllegalArgumentException("y < 0");
+            }
+            if (sourceRegion.width <= 0) {
+                throw new IllegalArgumentException("width <= 0");
+            }
+            if (sourceRegion.height <= 0) {
+                throw new IllegalArgumentException("height <= 0");
+            }
+
+            if (sourceRegion.width <= subsamplingXOffset) {
+                throw new IllegalArgumentException("width <= subsamplingXOffset");
+            }
+
+            if (sourceRegion.height <= subsamplingYOffset) {
+                throw new IllegalArgumentException("height <= subsamplingXOffset");
+            }
+            //-- clone it to avoid unexpected modifications
+            this.sourceRegion = (Rectangle) sourceRegion.clone();
+        } else {
+            this.sourceRegion = null;
+        }
+    }
+
+    /**
+     * Gets the source region.
+     * 
+     * @return the source region as Rectangle.
+     */
+    public Rectangle getSourceRegion() {
+        if (sourceRegion == null) {
+            return null;
+        }
+        //-- clone it to avoid unexpected modifications
+        return (Rectangle) sourceRegion.clone();
+    }
+
+    /**
+     * Sets the source subsampling. The sourceXSubsampling and 
+     * sourceYSubsampling parameters specify the number of rows 
+     * and columns to advance after every source pixel.
+     * 
+     * @param sourceXSubsampling the source X subsampling.
+     * @param sourceYSubsampling the source Y subsampling.
+     * @param subsamplingXOffset the subsampling X offset.
+     * @param subsamplingYOffset the subsampling Y offset.
+     */
+    public void setSourceSubsampling(int sourceXSubsampling,
+                                 int sourceYSubsampling,
+                                 int subsamplingXOffset,
+                                 int subsamplingYOffset) {
+
+        if (sourceXSubsampling <= 0) {
+            throw new IllegalArgumentException("sourceXSubsampling <= 0");
+        }
+        if (sourceYSubsampling <= 0) {
+            throw new IllegalArgumentException("sourceYSubsampling <= 0");
+        }
+
+        if (subsamplingXOffset <= 0 || subsamplingXOffset >= sourceXSubsampling) {
+            throw new IllegalArgumentException("subsamplingXOffset is wrong");
+        }
+
+        if (subsamplingYOffset <= 0 || subsamplingYOffset >= sourceYSubsampling) {
+            throw new IllegalArgumentException("subsamplingYOffset is wrong");
+        }
+
+        //-- does region contain pixels
+        if (sourceRegion != null) {
+            if (sourceRegion.width <= subsamplingXOffset ||
+                    sourceRegion.height <= subsamplingYOffset) {
+                throw new IllegalArgumentException("there are no pixels in region");
+            }
+        }
+
+        this.sourceXSubsampling = sourceXSubsampling;
+        this.sourceYSubsampling = sourceYSubsampling;
+        this.subsamplingXOffset = subsamplingXOffset;
+        this.subsamplingYOffset = subsamplingYOffset;
+    }
+
+    /**
+     * Gets the source X subsampling - the number of source 
+     * columns to advance for each pixel.
+     * 
+     * @return the source X subsampling.
+     */
+    public int getSourceXSubsampling() {
+        return sourceXSubsampling;
+    }
+
+    /**
+     * Gets the source Y subsampling - the number of source 
+     * rows to advance for each pixel.
+     * 
+     * @return the source Y subsampling.
+     */
+    public int getSourceYSubsampling() {
+        return sourceYSubsampling;
+    }
+
+    /**
+     * Gets the horizontal offset of the subsampling grid.
+     * 
+     * @return the horizontal offset of the subsampling grid.
+     */
+    public int getSubsamplingXOffset() {
+        return subsamplingXOffset;
+    }
+
+    /**
+     * Gets the vertical offset of the subsampling grid.
+     * 
+     * @return the vertical offset of the subsampling grid.
+     */
+    public int getSubsamplingYOffset() {
+        return subsamplingYOffset;
+    }
+
+    /**
+     * Sets the indices of the source bands.
+     * 
+     * @param sourceBands the indices of the source bands.
+     */
+    public void setSourceBands(int[] sourceBands) {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Gets the array of source bands.
+     * 
+     * @return the array of source bands.
+     */
+    public int[] getSourceBands() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Sets the specified ImageTypeSpecifier for the destination image.
+     * 
+     * @param destinationType the ImageTypeSpecifier.
+     */
+    public void setDestinationType(ImageTypeSpecifier destinationType) {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Gets the type of the destination image as an ImageTypeSpecifier. .
+     *  
+     * @return the ImageTypeSpecifier.
+     */
+    public ImageTypeSpecifier getDestinationType() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Sets the offset in the destination image where 
+     * the decoded pixels are placed as a result of reading, 
+     * or specified an area to be written while writing operation.
+     * 
+     * @param destinationOffset the destination offset.
+     */
+    public void setDestinationOffset(Point destinationOffset) {
+        if (destinationOffset == null) {
+            throw new IllegalArgumentException("destinationOffset == null!");
+        }
+        
+        this.destinationOffset = (Point) destinationOffset.clone();
+    }
+
+    /**
+     * Gets the offset in the destination image for placing pixels.
+     * 
+     * @return the offset in the destination image.
+     */
+    public Point getDestinationOffset() {
+        return (Point) destinationOffset.clone();        
+    }
+
+    /**
+     * Sets the IIOParamController to this IIOParam object for
+     * providing settings to this IIOParam.
+     * 
+     * @param controller the new IIOParamController.
+     */
+    public void setController(IIOParamController controller) {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Gets the current IIOParamController controller 
+     * for this IIOParam.
+     * 
+     * @return the current IIOParamController controller 
+     * for this IIOParam.
+     */
+    public IIOParamController getController() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Gets the default IIOParamController controller 
+     * for this IIOParam.
+     * 
+     * @return the default IIOParamController controller 
+     * for this IIOParam, or null.
+     */
+    public IIOParamController getDefaultController() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Returns true if IIOParamController is installed for 
+     * this IIOParam. 
+     * 
+     * @return true if IIOParamController is installed for 
+     * this IIOParam, false otherwise.
+     */
+    public boolean hasController() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    /**
+     * Activates the controller.
+     * 
+     * @return true, if successful, false otherwise.
+     */
+    public boolean activateController() {
+        // TODO implement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+}
diff --git a/awt/javax/imageio/IIOParamController.java b/awt/javax/imageio/IIOParamController.java
new file mode 100644
index 0000000..31522c1
--- /dev/null
+++ b/awt/javax/imageio/IIOParamController.java
@@ -0,0 +1,43 @@
+/*
+ *  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;
+
+/* 
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * The IIOParamController specifies an activate method that invokes the 
+ * controller.
+ */
+public interface IIOParamController {
+
+    /**
+     * Activates the controller. 
+     * 
+     * @param param the IIOParam.
+     * 
+     * @return true if the IIOParam has been modified, false otherwise.
+     */
+    boolean activate(IIOParam param);
+}
+
diff --git a/awt/javax/imageio/ImageIO.java b/awt/javax/imageio/ImageIO.java
new file mode 100644
index 0000000..d4cd1dd
--- /dev/null
+++ b/awt/javax/imageio/ImageIO.java
@@ -0,0 +1,777 @@
+/*
+ *  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;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.spi.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.Arrays;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+import java.net.URL;
+
+/**
+ * The ImageIO class provides static methods to perfom 
+ * reading and writing operations using registered
+ * ImageReader and ImageWriter objects.
+ */
+public final class ImageIO {
+
+    /** The Constant registry. */
+    private static final IIORegistry registry = IIORegistry.getDefaultInstance();
+
+    /**
+     * Instantiates a new image io.
+     */
+    private ImageIO() {}
+    
+
+    /**
+     * Scans for plug-ins in the class path, 
+     * loads spi classes, and registers them with the IIORegistry.
+     */
+    public static void scanForPlugins() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Sets flag which indicates whether a cache file is used when 
+     * creating ImageInputStreams and ImageOutputStreams or not.
+     * 
+     * @param useCache the use cache flag.
+     */
+    public static void setUseCache(boolean useCache) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the flag which indicates whether a cache file is used when 
+     * creating ImageInputStreams and ImageOutputStreams or not.
+     * This method returns the current value which is set by setUseCache
+     * method.
+     * 
+     * @return the use cache flag.
+     */
+    public static boolean getUseCache() {
+        // TODO implement
+        return false;
+    }
+
+    /**
+     * Sets the cache directory.
+     * 
+     * @param cacheDirectory the File which specifies a cache directory.
+     */
+    public static void setCacheDirectory(File cacheDirectory) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the directory where cache files are created, returned
+     * the file which is set by setCacheDirectory method, or null.
+     * 
+     * @return the File object which is set by setCacheDirectory method, 
+     * or null.
+     */
+    public static File getCacheDirectory() {
+        // TODO implement
+        //-- null indicates system-dep default temporary directory
+        return null;
+    }
+
+    /**
+     * Creates an ImageInputStream from the specified Object.
+     * The specified Object should obtain the input source
+     * such as File, or InputStream.   
+     * 
+     * @param input the input Object such as File, or InputStream.   
+     * 
+     * @return the ImageInputStream object, or null.
+     * 
+     * @throws IOException signals that an I/O exception has occurred.
+     */
+    public static ImageInputStream createImageInputStream(Object input)
+            throws IOException {
+
+        if (input == null) {
+            throw new IllegalArgumentException("input source cannot be NULL");
+        }
+
+        Iterator<ImageInputStreamSpi> it = registry.getServiceProviders(ImageInputStreamSpi.class, true);
+
+        while (it.hasNext()) {
+            ImageInputStreamSpi spi = it.next();
+            if (spi.getInputClass().isInstance(input)) {
+                return spi.createInputStreamInstance(input);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Creates an ImageOutputStream using the specified Object.
+     * The specified Object should obtain the output source
+     * such as File, or OutputStream.   
+     * 
+     * @param output the output Object such as File, or OutputStream.   
+     * 
+     * @return the ImageOutputStream object, or null.
+     * 
+     * @throws IOException signals that an I/O exception has occurred.
+     */
+    public static ImageOutputStream createImageOutputStream(Object output)
+            throws IOException {
+        if (output == null) {
+            throw new IllegalArgumentException("output destination cannot be NULL");
+        }
+
+        Iterator<ImageOutputStreamSpi> it = registry.getServiceProviders(ImageOutputStreamSpi.class, true);
+
+        while (it.hasNext()) {
+            ImageOutputStreamSpi spi = it.next();
+            if (spi.getOutputClass().isInstance(output)) {
+                // todo - use getUseCache and getCacheDir here
+                return spi.createOutputStreamInstance(output);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets the array of format names as String which can be 
+     * decoded by registered ImageReader objects.
+     * 
+     * @return the array of format names.
+     */
+    public static String[] getReaderFormatNames() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the array of MIME types as String which can be 
+     * decoded by registered ImageReader objects.
+     * 
+     * @return the array of MIME types.
+     */
+    public static String[] getReaderMIMETypes() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the Iterator of registered ImageReader which are able to 
+     * decode an imput data specified by input Object.
+     * 
+     * @param input the input Object with encoded data such as 
+     * ImageInputStream object.
+     * 
+     * @return the Iterator of registered ImageReader. 
+     */
+    public static Iterator<ImageReader> getImageReaders(Object input) {
+        if (input == null) {
+            throw new NullPointerException("input cannot be NULL");
+        }
+
+        Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
+                new CanReadFilter(input), true);
+
+        return new SpiIteratorToReadersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator of registered ImageReader which are able to 
+     * decode the specified format.
+     * 
+     * @param formatName the format name such as "jpeg", or "gif".
+     * 
+     * @return the Iterator of registered ImageReader.
+     */
+    public static Iterator<ImageReader> getImageReadersByFormatName(String formatName) {
+        if (formatName == null) {
+            throw new NullPointerException("format name cannot be NULL");
+        }
+
+        Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
+                new FormatFilter(formatName), true);
+
+        return new SpiIteratorToReadersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator which lists the registered ImageReader objects that
+     * are able to decode files with the specified suffix.
+     * 
+     * @param fileSuffix the file suffix such as "jpg".
+     * 
+     * @return the Iterator of registered ImageReaders.
+     */
+    public static Iterator<ImageReader> getImageReadersBySuffix(String fileSuffix) {
+        if (fileSuffix == null) {
+            throw new NullPointerException("suffix cannot be NULL");
+        }
+        Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class,
+                new SuffixFilter(fileSuffix), true);
+
+        return new SpiIteratorToReadersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator of registered ImageReader objects that
+     * are able to decode files with the specified MIME type.
+     * 
+     * @param MIMEType the MIME type such as "image/jpeg".
+     * 
+     * @return the Iterator of registered ImageReaders.
+     */
+    public static Iterator<ImageReader> getImageReadersByMIMEType(String MIMEType) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an array of Strings giving the names of the formats supported 
+     * by registered ImageWriter objects.
+     * 
+     * @return the array of format names.
+     */
+    public static String[] getWriterFormatNames() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an array of Strings giving the MIME types of the formats supported 
+     * by registered ImageWriter objects.
+     * 
+     * @return the array of MIME types.
+     */
+    public static String[] getWriterMIMETypes() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the Iterator which lists the registered ImageReader objects that
+     * are able to encode the specified image format.
+     * 
+     * @param formatName the image format name such as "jpeg".
+     * 
+     * @return the Iterator of registered ImageWriter.
+     */
+    public static Iterator<ImageWriter> getImageWritersByFormatName(String formatName) {
+        if (formatName == null) {
+            throw new NullPointerException("format name cannot be NULL");
+        }
+
+        Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class,
+                new FormatFilter(formatName), true);
+
+        return new SpiIteratorToWritersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator which lists the registered ImageReader objects that
+     * are able to encode the specified suffix.
+     * 
+     * @param fileSuffix the file suffix such as "jpg".
+     * 
+     * @return the Iterator of registered ImageWriter.
+     */
+    public static Iterator<ImageWriter> getImageWritersBySuffix(String fileSuffix) {
+        if (fileSuffix == null) {
+            throw new NullPointerException("suffix cannot be NULL");
+        }
+        Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class,
+                new SuffixFilter(fileSuffix), true);
+        return new SpiIteratorToWritersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator which lists the registered ImageReader objects that
+     * are able to encode the specified MIME type.
+     * 
+     * @param MIMEType the MIME type such as "image/jpeg".
+     * 
+     * @return the Iterator of registered ImageWriter.
+     */
+    public static Iterator<ImageWriter> getImageWritersByMIMEType(String MIMEType) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an ImageWriter object which corresponds to the 
+     * specified ImageReader, or returns null if the specified
+     * ImageReader is not registered. 
+     * 
+     * @param reader the specified ImageReader.
+     * 
+     * @return the ImageWriter, or null.
+     */
+    public static ImageWriter getImageWriter(ImageReader reader) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an ImageReader object which corresponds to the 
+     * specified ImageWriter, or returns null if the specified
+     * ImageWriter is not registered. 
+     * 
+     * @param writer the registered ImageWriter object.
+     * 
+     * @return the ImageReader.
+     */
+    public static ImageReader getImageReader(ImageWriter writer) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the Iterator of ImageWriter objects which are able to
+     * encode images with the specified ImageTypeSpecifier and
+     * format.
+     * 
+     * @param type the ImageTypeSpecifier, which defines layout.
+     * @param formatName the format name.
+     * 
+     * @return the Iterator of ImageWriter objects.
+     */
+    public static Iterator<ImageWriter> getImageWriters(ImageTypeSpecifier type,
+                                           String formatName) {
+        if (type == null) {
+            throw new NullPointerException("type cannot be NULL");
+        }
+
+        if (formatName == null) {
+            throw new NullPointerException("format name cannot be NULL");
+        }
+
+        Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class,
+                new FormatAndEncodeFilter(type, formatName), true);
+
+        return new SpiIteratorToWritersIteratorWrapper(it);
+    }
+
+    /**
+     * Gets the Iterator of registered ImageTranscoders which 
+     * are able to transcode the metadata of the specified
+     * ImageReader object to a suitable object for encoding 
+     * by the specified ImageWriter.
+     * 
+     * @param reader the specified ImageReader.
+     * @param writer the specified ImageWriter.
+     * 
+     * @return the Iterator of registered ImageTranscoders.
+     */
+    public static Iterator<ImageTranscoder> getImageTranscoders(ImageReader reader,
+                                               ImageWriter writer) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Reads image data from the specified File and decodes it using 
+     * the appropriate registered ImageReader object. 
+     * The File is wrapped in an ImageInputStream.
+     * 
+     * @param input the File to be read.
+     * 
+     * @return the BufferedImage decoded from the specified File, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static BufferedImage read(File input) throws IOException {
+        if (input == null) {
+            throw new IllegalArgumentException("input == null!");
+        }
+
+        ImageInputStream stream = createImageInputStream(input);
+        return read(stream);
+    }
+
+    /**
+     * Reads image data from the specified InputStream and decodes it 
+     * using an appropriate registered an ImageReader object.
+     * 
+     * @param input the InputStream.
+     * 
+     * @return the BufferedImage decoded from the specified InputStream,
+     * or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static BufferedImage read(InputStream input) throws IOException {
+        if (input == null) {
+            throw new IllegalArgumentException("input == null!");
+        }
+
+        ImageInputStream stream = createImageInputStream(input);
+        return read(stream);
+    }
+
+    /**
+     * Reads image data from the specified URL and decodes it using 
+     * the appropriate registered ImageReader object. 
+     *  
+     * @param input the URL to be read.
+     * 
+     * @return the BufferedImage decoded from the specified URL, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static BufferedImage read(URL input) throws IOException {
+        if (input == null) {
+            throw new IllegalArgumentException("input == null!");
+        }
+
+        InputStream stream = input.openStream();
+        BufferedImage res = read(stream);
+        stream.close();
+        
+        return res;
+    }
+
+    /**
+     * Reads image data from the specified ImageInputStream and decodes it 
+     * using appropriate registered an ImageReader object.
+     * 
+     * @param stream the ImageInputStream.
+     * 
+     * @return the BufferedImage decoded from the specified ImageInputStream,
+     * or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static BufferedImage read(ImageInputStream stream) throws IOException {
+        if (stream == null) {
+            throw new IllegalArgumentException("stream == null!");
+        }
+
+        Iterator<ImageReader> imageReaders = getImageReaders(stream);
+        if (!imageReaders.hasNext()) {
+            return null;
+        }
+
+        ImageReader reader = imageReaders.next();
+        reader.setInput(stream, false, true);
+        BufferedImage res = reader.read(0);
+        reader.dispose();
+
+        try {
+            stream.close();
+        } catch (IOException e) {
+            // Stream could be already closed, proceed silently in this case
+        }
+        
+        return res;
+    }
+
+    /**
+     * Writes the specified image in the specified format (using an 
+     * appropriate ImageWriter) to the specified ImageOutputStream.
+     * 
+     * @param im the RenderedImage.
+     * @param formatName the format name.
+     * @param output the ImageOutputStream where Image to be written.
+     * 
+     * @return true, if Image is written successfully, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static boolean write(RenderedImage im,
+                                String formatName,
+                                ImageOutputStream output)
+            throws IOException {
+
+        if (im == null) {
+            throw new IllegalArgumentException("image cannot be NULL");
+        }
+        if (formatName == null) {
+            throw new IllegalArgumentException("format name cannot be NULL");
+        }
+        if (output == null) {
+            throw new IllegalArgumentException("output cannot be NULL");
+        }
+
+        Iterator<ImageWriter> it = getImageWriters(ImageTypeSpecifier.createFromRenderedImage(im), formatName);
+        if (it.hasNext()) {
+            ImageWriter writer = it.next();
+            writer.setOutput(output);
+            writer.write(im);
+            output.flush();
+            writer.dispose();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Writes the specified image in the specified format (using an 
+     * appropriate ImageWriter) to the specified File.
+     * 
+     * @param im the RenderedImage.
+     * @param formatName the format name.
+     * @param output the output File where Image to be written.
+     * 
+     * @return true, if Image is written successfully, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static boolean write(RenderedImage im,
+                                String formatName,
+                                File output)
+            throws IOException {
+
+        if (output == null) {
+            throw new IllegalArgumentException("output cannot be NULL");
+        }
+
+        if (output.exists()) {
+            output.delete();
+        }
+
+        ImageOutputStream ios = createImageOutputStream(output);
+        boolean rt = write(im, formatName, ios);
+        ios.close();
+        return rt;
+    }
+
+    /**
+     * Writes the specified image in the specified format (using an 
+     * appropriate ImageWriter) to the specified OutputStream.
+     * 
+     * @param im the RenderedImage.
+     * @param formatName the format name.
+     * @param output the OutputStream where Image is to be written.
+     * 
+     * @return true, if Image is written successfully, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public static boolean write(RenderedImage im,
+                                String formatName,
+                                OutputStream output)
+            throws IOException {
+
+        if (output == null) {
+            throw new IllegalArgumentException("output cannot be NULL");
+        }
+
+        ImageOutputStream ios = createImageOutputStream(output);
+        boolean rt = write(im, formatName, ios);
+        ios.close();
+        return rt;
+    }
+
+
+    /**
+     * Filter to match spi by format name.
+     */
+    static class FormatFilter implements ServiceRegistry.Filter {
+        
+        /** The name. */
+        private String name;
+
+        /**
+         * Instantiates a new format filter.
+         * 
+         * @param name the name
+         */
+        public FormatFilter(String name) {
+            this.name = name;
+        }
+
+        public boolean filter(Object provider) {
+            ImageReaderWriterSpi spi = (ImageReaderWriterSpi) provider;
+            return Arrays.asList(spi.getFormatNames()).contains(name);
+        }
+    }
+
+    /**
+     * Filter to match spi by format name and encoding possibility.
+     */
+    static class FormatAndEncodeFilter extends FormatFilter {
+
+        /** The type. */
+        private ImageTypeSpecifier type;
+
+        /**
+         * Instantiates a new format and encode filter.
+         * 
+         * @param type the type
+         * @param name the name
+         */
+        public FormatAndEncodeFilter(ImageTypeSpecifier type, String name) {
+            super(name);
+            this.type = type;
+        }
+
+        @Override
+        public boolean filter(Object provider) {
+            ImageWriterSpi spi = (ImageWriterSpi) provider;
+            return super.filter(provider) && spi.canEncodeImage(type);
+        }
+    }
+
+    /**
+     * Filter to match spi by suffix.
+     */
+    static class SuffixFilter implements ServiceRegistry.Filter {
+        
+        /** The suf. */
+        private String suf;
+
+        /**
+         * Instantiates a new suffix filter.
+         * 
+         * @param suf the suf
+         */
+        public SuffixFilter(String suf) {
+            this.suf = suf;
+        }
+
+        public boolean filter(Object provider) {
+            ImageReaderWriterSpi spi = (ImageReaderWriterSpi) provider;
+            return Arrays.asList(spi.getFileSuffixes()).contains(suf);
+        }
+    }
+
+    /**
+     * Filter to match spi by decoding possibility.
+     */
+    static class CanReadFilter implements ServiceRegistry.Filter {
+        
+        /** The input. */
+        private Object input;
+
+        /**
+         * Instantiates a new can read filter.
+         * 
+         * @param input the input
+         */
+        public CanReadFilter(Object input) {
+            this.input = input;
+        }
+
+        public boolean filter(Object provider) {
+            ImageReaderSpi spi = (ImageReaderSpi) provider;
+            try {
+                return spi.canDecodeInput(input);
+            } catch (IOException e) {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Wraps Spi's iterator to ImageWriter iterator.
+     */
+    static class SpiIteratorToWritersIteratorWrapper implements Iterator<ImageWriter> {
+
+        /** The backend. */
+        private Iterator<ImageWriterSpi> backend;
+
+        /**
+         * Instantiates a new spi iterator to writers iterator wrapper.
+         * 
+         * @param backend the backend
+         */
+        public SpiIteratorToWritersIteratorWrapper(Iterator<ImageWriterSpi> backend) {
+            this.backend = backend;
+        }
+
+        /**
+         * Next.
+         * 
+         * @return the image writer
+         */
+        public ImageWriter next() {
+            try {
+                return backend.next().createWriterInstance();
+            } catch (IOException e) {
+                e.printStackTrace();
+                return null;
+            }
+        }
+
+        /**
+         * Checks for next.
+         * 
+         * @return true, if successful
+         */
+        public boolean hasNext() {
+            return backend.hasNext();
+        }
+
+        /**
+         * Removes the.
+         */
+        public void remove() {
+            throw new UnsupportedOperationException("Use deregisterServiceprovider instead of Iterator.remove()");
+        }
+    }
+
+    /**
+     * Wraps spi's iterator to ImageReader iterator.
+     */
+    static class SpiIteratorToReadersIteratorWrapper implements Iterator<ImageReader> {
+        
+        /** The backend. */
+        private Iterator<ImageReaderSpi> backend;
+
+        /**
+         * Instantiates a new spi iterator to readers iterator wrapper.
+         * 
+         * @param backend the backend
+         */
+        public SpiIteratorToReadersIteratorWrapper(Iterator<ImageReaderSpi> backend) {
+            this.backend = backend;
+        }
+
+        /**
+         * Next.
+         * 
+         * @return the image reader
+         */
+        public ImageReader next() {
+            try {
+                return backend.next().createReaderInstance();
+            } catch (IOException e) {
+                e.printStackTrace();
+                return null;
+            }
+        }
+
+        /**
+         * Checks for next.
+         * 
+         * @return true, if successful
+         */
+        public boolean hasNext() {
+            return backend.hasNext();
+        }
+
+        /**
+         * Removes the.
+         */
+        public void remove() {
+            throw new UnsupportedOperationException("Use deregisterServiceprovider instead of Iterator.remove()");
+        }
+    }
+}
diff --git a/awt/javax/imageio/ImageReadParam.java b/awt/javax/imageio/ImageReadParam.java
new file mode 100644
index 0000000..e67ed7d
--- /dev/null
+++ b/awt/javax/imageio/ImageReadParam.java
@@ -0,0 +1,193 @@
+/*
+ *  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;
+
+import java.awt.Dimension;
+import java.awt.image.BufferedImage;
+
+/*
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * The ImageReadParam class provides information to the ImageReader about
+ * how an image is to be decoded.
+ */
+
+public class ImageReadParam extends IIOParam {
+
+    /** 
+     * This flag indicates if this ImageReadParam supports setting the source 
+     * rendering size.  
+     */
+    protected boolean canSetSourceRenderSize;
+    
+    /** 
+     * The destination BufferedImage. 
+     */
+    protected BufferedImage destination;
+    
+    /** The destination bands. */
+    protected int[] destinationBands;
+    
+    /** 
+     * The minimum progressive pass.  
+     */
+    protected int minProgressivePass;
+    
+    /** 
+     * The number of progressive passes.  
+     */
+    protected int numProgressivePasses;
+    
+    /** The source render size. */
+    protected Dimension sourceRenderSize;
+
+    /**
+     * Returns true if this ImageReaderParam supports rendering a
+     * source image at an arbitrary size.
+     * 
+     * @return true if this ImageReaderParam supports rendering a
+     * source image at an arbitrary size, false otherwise.
+     */
+    public boolean canSetSourceRenderSize() {
+        return canSetSourceRenderSize;
+    }
+
+    /**
+     * Gets the current destination image as BufferedImage.
+     * 
+     * @return the BufferedImage which represents the destination.
+     */
+    public BufferedImage getDestination() {
+        return destination;
+    }
+
+    /**
+     * Gets the indices of destination bands.
+     * 
+     * @return the array of destination bands.
+     */
+    public int[] getDestinationBands() {
+        return destinationBands;
+    }
+
+    /**
+     * Gets the index of the maximum pass to be decoded.
+     * This method returns Integer.MAX_VALUE, if 
+     * getSourceNumProgressivePasses() method returns value
+     * that is equal to Integer.MAX_VALUE. Otherwise
+     * this method returns 
+     * getSourceMinProgressivePass() + getSourceNumProgressivePasses() - 1.
+     * 
+     * @return the index of the maximum pass to be decoded.
+     */
+    public int getSourceMaxProgressivePass() {
+        if (getSourceNumProgressivePasses() == Integer.MAX_VALUE) {
+            return Integer.MAX_VALUE;
+        }
+        return getSourceMinProgressivePass() + getSourceNumProgressivePasses() - 1;
+    }
+
+    /**
+     * Gets the index of the minimum progressive pass that is decoded,
+     * default is 0. 
+     * 
+     * @return the index of the minimum progressive pass that is decoded,
+     * default is 0.
+     */
+    public int getSourceMinProgressivePass() {
+        return minProgressivePass;
+    }
+
+    /**
+     * Gets the number of progressive passes.
+     * The default value is Integer.MAX_VALUE. 
+     * 
+     * @return the number of progressive passes.
+     */
+    public int getSourceNumProgressivePasses() {
+        return numProgressivePasses;
+    }
+
+    /**
+     * Gets the dimension of source image which will be rendered
+     * during decoding process.
+     * 
+     * @return the source render size.
+     */
+    public Dimension getSourceRenderSize() {
+        return sourceRenderSize;
+    }
+
+    /**
+     * Sets the specified destination image.
+     * This image will be used by read, readAll, and readRaster methods,
+     * and a reference to it will be returned by those methods.
+     * 
+     * @param destination the destination image.
+     */
+    public void setDestination(BufferedImage destination) {
+        this.destination = destination;
+    }
+
+    /**
+     * Sets the indices of the destination bands.
+     * 
+     * @param destinationBands the indices of the destination bands.
+     */
+    public void setDestinationBands(int[] destinationBands) {
+        this.destinationBands = destinationBands;
+    }
+
+    @Override
+    public void setDestinationType(ImageTypeSpecifier destinationType) {
+        this.destinationType = destinationType;
+    }
+
+    /**
+     * Sets the source progressive passes.
+     * 
+     * @param minPass the index of the minimum pass to be decoded.
+     * @param numPasses the number of passes to be decoded.
+     */
+    public void setSourceProgressivePasses(int minPass, int numPasses) {
+        minProgressivePass = minPass;
+        numProgressivePasses = numPasses;
+    }
+
+    /**
+     * Sets the dimension size of source image if an
+     * image can be rendered at an arbitrary size.
+     * 
+     * @param size the size of rendered image.
+     * 
+     * @throws UnsupportedOperationException the unsupported operation exception
+     */
+    public void setSourceRenderSize(Dimension size) throws UnsupportedOperationException {
+        if (!canSetSourceRenderSize) {
+            throw new UnsupportedOperationException("can't set source renderer size");
+        }
+        sourceRenderSize = size;        
+    }
+}
+
diff --git a/awt/javax/imageio/ImageReader.java b/awt/javax/imageio/ImageReader.java
new file mode 100644
index 0000000..780de26
--- /dev/null
+++ b/awt/javax/imageio/ImageReader.java
@@ -0,0 +1,1100 @@
+/*
+ *  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;
+
+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 java.util.Locale;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Set;
+import java.io.IOException;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.*;
+
+/**
+ * The ImageReader class is an abstract class for decoding images.
+ * ImageReader objects are instantiated by the service provider 
+ * interface, ImageReaderSpi class, for the specific format. 
+ * ImageReaderSpi class should be registered with the IIORegistry, 
+ * which uses them for format recognition and presentation of available 
+ * format readers and writers.
+ */
+public abstract class ImageReader {
+
+    /** The originating provider. */
+    protected ImageReaderSpi originatingProvider;
+
+    /** The input object such as ImageInputStream. */
+    protected Object input;
+
+    /** The seek forward only. */
+    protected boolean seekForwardOnly;
+
+    /** 
+     * The ignore metadata flag indicates whether current input source 
+     * has been marked as metadata is allowed to be ignored by setInput. 
+     */
+    protected boolean ignoreMetadata;
+
+    /** The minimum index. */
+    protected int minIndex;
+
+    /** The available locales. */
+    protected Locale[] availableLocales;
+
+    /** The locale. */
+    protected Locale locale;
+
+    /** The list of warning listeners. */
+    protected List<IIOReadWarningListener> warningListeners;
+
+    /** The list of warning locales. */
+    protected List<Locale> warningLocales;
+
+    /** The list of progress listeners. */
+    protected List<IIOReadProgressListener> progressListeners;
+
+    /** The list of update listeners. */
+    protected List<IIOReadUpdateListener> updateListeners;
+
+    /**
+     * Instantiates a new ImageReader.
+     * 
+     * @param originatingProvider the ImageReaderSpi which 
+     * instanties this ImageReader.
+     */
+    protected ImageReader(ImageReaderSpi originatingProvider) {
+        this.originatingProvider = originatingProvider;
+    }
+
+    /**
+     * Gets the format name of this input source.
+     * 
+     * @return the format name of this input source.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public String getFormatName() throws IOException {
+        return originatingProvider.getFormatNames()[0];
+    }
+
+    /**
+     * Gets the ImageReaderSpi which instantiated this ImageReader. 
+     * 
+     * @return the ImageReaderSpi.
+     */
+    public ImageReaderSpi getOriginatingProvider() {
+        return originatingProvider;
+    }
+
+    /**
+     * Sets the specified Object as the input source of this ImageReader. 
+     * 
+     * @param input the input source, it can 
+     * be an ImageInputStream or other supported objects.
+     * @param seekForwardOnly indicates whether the stream must
+     * be read sequentially from its current starting point.
+     * @param ignoreMetadata parameter which indicates
+     * if metadata may be ignored during reads or not.
+     */
+    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
+        if (input != null) {
+            if (!isSupported(input) && !(input instanceof ImageInputStream)) {
+                throw new IllegalArgumentException("input " + input + " is not supported");
+            }
+        }
+        this.minIndex = 0;
+        this.seekForwardOnly = seekForwardOnly;
+        this.ignoreMetadata = ignoreMetadata;
+        this.input = input;
+    }
+
+    /**
+     * Checks if is supported.
+     * 
+     * @param input the input
+     * 
+     * @return true, if is supported
+     */
+    private boolean isSupported(Object input) {
+        ImageReaderSpi spi = getOriginatingProvider();
+        if (null != spi) {
+            Class[] outTypes = spi.getInputTypes();
+            for (Class<?> element : outTypes) {
+                if (element.isInstance(input)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Sets the specified Object as the input source of this ImageReader.
+     * Metadata is not ignored.
+     * 
+     * @param input the input source, it can 
+     * be an ImageInputStream or other supported objects.
+     * @param seekForwardOnly indicates whether the stream must
+     * be read sequentially from its current starting point.
+     */
+    public void setInput(Object input, boolean seekForwardOnly) {
+        setInput(input, seekForwardOnly, false);
+    }
+
+    /**
+     * Sets the specified Object as the input source of this ImageReader.
+     * Metadata is not ignored and forward seeking is not required.
+     * 
+     * @param input the input source, it can 
+     * be ImageInputStream or other objects.
+     */
+    public void setInput(Object input) {
+        setInput(input, false, false);
+    }
+
+    /**
+     * Gets the input source object of this ImageReader, or returns null.
+     * 
+     * @return the the input source object such as ImageInputStream,
+     * or null.
+     */
+    public Object getInput() {
+        return input;
+    }
+
+    /**
+     * Checks if the input source supports only forward reading, or not.
+     * 
+     * @return true, if the input source supports only forward reading, 
+     * false otherwise.
+     */
+    public boolean isSeekForwardOnly() {
+        return seekForwardOnly;
+    }
+
+    /**
+     * Returns true if the current input source allows 
+     * to metadata to be ignored by passing true as 
+     * the ignoreMetadata argument to the setInput method.
+     * 
+     * @return true, if true if the current input source allows 
+     * to metadata to be ignored by passing true as 
+     * the ignoreMetadata argument to the setInput method.
+     */
+    public boolean isIgnoringMetadata() {
+        return ignoreMetadata;
+    }
+
+    /**
+     * Gets the minimum valid index for reading an image, thumbnail, 
+     * or image metadata. 
+     * 
+     * @return the minimum valid index for reading an image, thumbnail, 
+     * or image metadata.
+     */
+    public int getMinIndex() {
+        return minIndex;
+    }
+
+    /**
+     * Gets the available locales.
+     * 
+     * @return an array of the available locales.
+     */
+    public Locale[] getAvailableLocales() {
+        return availableLocales;
+    }
+
+    /**
+     * Sets the locale to this ImageReader.
+     * 
+     * @param locale the Locale.
+     */
+    public void setLocale(Locale locale) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Gets the locale of this ImageReader.
+     * 
+     * @return the locale of this ImageReader.
+     */
+    public Locale getLocale() {
+        return locale;
+    }
+
+    /**
+     * Gets the number of images available in the current input source.
+     * 
+     * @param allowSearch the parameter which indicates what
+     * a search is required; if false, the reader may return -1  
+     * without searching.
+     * 
+     * @return the number of images.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract int getNumImages(boolean allowSearch) throws IOException;
+
+    /**
+     * Gets the width of the specified image in input source.
+     * 
+     * @param imageIndex the image index.
+     * 
+     * @return the width in pixels.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract int getWidth(int imageIndex) throws IOException;
+
+    /**
+     * Gets the height of the specified image in input source.
+     * 
+     * @param imageIndex the image index.
+     * 
+     * @return the height in pixels.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract int getHeight(int imageIndex) throws IOException;
+
+    /**
+     * Checks if the storage format of the specified image places 
+     * an impediment on random pixels access or not. 
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return true, if the storage format of the specified image places 
+     * an impediment on random pixels access, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean isRandomAccessEasy(int imageIndex) throws IOException {
+        return false; //def
+    }
+
+    /**
+     * Gets the aspect ratio (width devided by height) of the image.
+     * 
+     * @param imageIndex the image index.
+     * 
+     * @return the aspect ratio of the image.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public float getAspectRatio(int imageIndex) throws IOException {
+        return (float) getWidth(imageIndex) / getHeight(imageIndex);
+    }
+
+    /**
+     * Gets an ImageTypeSpecifier which indicates the type of the 
+     * specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the ImageTypeSpecifier.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public ImageTypeSpecifier getRawImageType(int imageIndex) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Gets an Iterator of ImageTypeSpecifier objects which are associated
+     * with image types that may be used when decoding specified image.
+     * 
+     * @param imageIndex the image index.
+     * 
+     * @return an Iterator of ImageTypeSpecifier objects.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException;
+
+    /**
+     * Gets the default ImageReadParam object.
+     * 
+     * @return the ImageReadParam object.
+     */
+    public ImageReadParam getDefaultReadParam() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Gets an IIOMetadata object for this input source.
+     * 
+     * @return the IIOMetadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract IIOMetadata getStreamMetadata() throws IOException;
+
+    /**
+     * Gets an IIOMetadata object for this input source.
+     * 
+     * @param formatName the desired metadata format to be used in the 
+     * returned IIOMetadata object.
+     * @param nodeNames the node names of the document.
+     * 
+     * @return the IIOMetadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public IIOMetadata getStreamMetadata(String formatName, Set<String> nodeNames)
+            throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Gets the image metadata of the specified image in input source.
+     * 
+     * @param imageIndex the image index.
+     * 
+     * @return the IIOMetadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract IIOMetadata getImageMetadata(int imageIndex) throws IOException;
+
+    /**
+     * Gets the image metadata of the specified image input source.
+     * 
+     * @param imageIndex the image index.
+     * @param formatName the desired metadata format to be used in the 
+     * returned IIOMetadata object.
+     * @param nodeNames the node names which can be contained in
+     * the document.
+     * 
+     * @return the IIOMetadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public IIOMetadata getImageMetadata(int imageIndex, String formatName,
+                                        Set<String> nodeNames) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Reads the specified image and returns it as a BufferedImage
+     * using the default ImageReadParam.
+     *  
+     * @param imageIndex the image index.
+     * 
+     * @return the BufferedImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public BufferedImage read(int imageIndex) throws IOException {
+        return read(imageIndex, null);
+    }
+
+    /**
+     * Reads the specified image and returns it as a BufferedImage
+     * using the specified ImageReadParam.
+     * 
+     * @param imageIndex the image index.
+     * @param param the ImageReadParam.
+     * 
+     * @return the BufferedImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract BufferedImage read(int imageIndex, ImageReadParam param) throws IOException;
+
+    /**
+     * Reads the specified image and returns an IIOImage with this image,
+     * thumbnails, and metadata for this image, using 
+     * the specified ImageReadParam.
+     * 
+     * @param imageIndex the image index.
+     * @param param the ImageReadParam.
+     * 
+     * @return the IIOImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public IIOImage readAll(int imageIndex, ImageReadParam param) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Returns an Iterator of IIOImages from the input source. 
+     * 
+     * @param params the Iterator of ImageReadParam objects.
+     * 
+     * @return the iterator of IIOImages.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public Iterator<IIOImage> readAll(Iterator<? extends ImageReadParam> params) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Checks whether or not this plug-in supports reading a Raster.
+     * 
+     * @return true, if this plug-in supports reading a Raster,
+     * false otherwise.
+     */
+    public boolean canReadRaster() {
+        return false; //def
+    }
+
+    /**
+     * Reads a new Raster object which contains the raw pixel data from 
+     * the image. 
+     * 
+     * @param imageIndex the image index.
+     * @param param the ImageReadParam.
+     * 
+     * @return the Raster.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public Raster readRaster(int imageIndex, ImageReadParam param) throws IOException {
+        throw new UnsupportedOperationException("Unsupported");
+    }
+
+    /**
+     * Checks if the specified image has tiles or not.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return true, if the specified image has tiles,
+     * false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean isImageTiled(int imageIndex) throws IOException {
+        return false; //def
+    }
+
+    /**
+     * Gets the tile width in the specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the tile width.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getTileWidth(int imageIndex) throws IOException {
+        return getWidth(imageIndex); //def
+    }
+
+    /**
+     * Gets the tile height in the specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the tile height.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getTileHeight(int imageIndex) throws IOException {
+        return getHeight(imageIndex); //def
+    }
+
+    /**
+     * Gets the X coordinate of the upper left corner of the tile grid in the 
+     * specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the X coordinate of the upper left corner of the tile grid.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getTileGridXOffset(int imageIndex) throws IOException {
+        return 0; //def
+    }
+
+    /**
+     * Gets the Y coordinate of the upper left corner of the tile grid in the 
+     * specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the Y coordinate of the upper left corner of the tile grid.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getTileGridYOffset(int imageIndex) throws IOException {
+        return 0; //def
+    }
+
+    /**
+     * Reads the tile specified by the tileX and tileY parameters
+     * of the specified image and returns it as a BufferedImage. 
+     * 
+     * @param imageIndex the image index.
+     * @param tileX the X index of tile.
+     * @param tileY the Y index of tile.
+     * 
+     * @return the BufferedImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public BufferedImage readTile(int imageIndex, int tileX, int tileY) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Reads the tile specified by the tileX and tileY parameters
+     * of the specified image and returns it as a Raster. 
+     * 
+     * @param imageIndex the image index.
+     * @param tileX the X index of tile.
+     * @param tileY the Y index of tile.
+     * 
+     * @return the Raster.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public Raster readTileRaster(int imageIndex, int tileX, int tileY) throws IOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Reads the specified image using the specified 
+     * ImageReadParam and returns it as a RenderedImage.
+     * 
+     * @param imageIndex the image index.
+     * @param param the ImageReadParam.
+     * 
+     * @return the RenderedImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public RenderedImage readAsRenderedImage(int imageIndex, ImageReadParam param) throws IOException {
+        return read(imageIndex, param);
+    }
+
+    /**
+     * Returns true if the image format supported by this reader 
+     * supports thumbnail preview images.
+     * 
+     * @return true if the image format supported by this reader 
+     * supports thumbnail preview images, false otherwise.
+     */
+    public boolean readerSupportsThumbnails() {
+        return false; //def
+    }
+
+    /**
+     * Checks if the specified image has thumbnails or not.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return true, if the specified image has thumbnails,
+     * false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean hasThumbnails(int imageIndex) throws IOException {
+        return getNumThumbnails(imageIndex) > 0; //def
+    }
+
+    /**
+     * Gets the number of thumbnails for the specified image.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return the number of thumbnails.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getNumThumbnails(int imageIndex) throws IOException {
+        return 0; //def
+    }
+
+    /**
+     * Gets the width of the specified thumbnail for the specified image.
+     * 
+     * @param imageIndex the image's index.
+     * @param thumbnailIndex the thumbnail's index.
+     * 
+     * @return the thumbnail width.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getThumbnailWidth(int imageIndex, int thumbnailIndex) throws IOException {
+        return readThumbnail(imageIndex, thumbnailIndex).getWidth();  //def
+    }
+
+    /**
+     * Gets the height of the specified thumbnail for the specified image.
+     * 
+     * @param imageIndex the image's index.
+     * @param thumbnailIndex the thumbnail's index.
+     * 
+     * @return the thumbnail height.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public int getThumbnailHeight(int imageIndex, int thumbnailIndex) throws IOException {
+        return readThumbnail(imageIndex, thumbnailIndex).getHeight();  //def
+    }
+
+    /**
+     * Reads the thumbnail image for the specified image
+     * as a BufferedImage.
+     *  
+     * @param imageIndex the image index.
+     * @param thumbnailIndex the thumbnail index.
+     * 
+     * @return the BufferedImage.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public BufferedImage readThumbnail(int imageIndex, int thumbnailIndex) throws IOException {
+        throw new UnsupportedOperationException("Unsupported"); //def
+    }
+
+    /**
+     * Requests an abort operation for current reading operation. 
+     */
+    public void abort() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Checks whether or not a request to abort the current read operation 
+     * has been made successfully.
+     * 
+     * @return true, if the request to abort the current read operation 
+     * has been made successfully, false otherwise.
+     */
+    protected boolean abortRequested() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Clears all previous abort request, and abortRequested returns false
+     * after calling this method.
+     */
+    protected void clearAbortRequest() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Adds the IIOReadWarningListener.
+     * 
+     * @param listener the IIOReadWarningListener.
+     */
+    public void addIIOReadWarningListener(IIOReadWarningListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes the specified IIOReadWarningListener.
+     * 
+     * @param listener the IIOReadWarningListener to be removed.
+     */
+    public void removeIIOReadWarningListener(IIOReadWarningListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes all registered IIOReadWarningListeners.
+     */
+    public void removeAllIIOReadWarningListeners() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Adds the IIOReadProgressListener.
+     * 
+     * @param listener the IIOReadProgressListener.
+     */
+    public void addIIOReadProgressListener(IIOReadProgressListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes the specified IIOReadProgressListener.
+     * 
+     * @param listener the IIOReadProgressListener to be removed.
+     */
+    public void removeIIOReadProgressListener(IIOReadProgressListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes registered IIOReadProgressListeners.
+     */
+    public void removeAllIIOReadProgressListeners() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Adds the IIOReadUpdateListener.
+     * 
+     * @param listener the IIOReadUpdateListener.
+     */
+    public void addIIOReadUpdateListener(IIOReadUpdateListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes the specified IIOReadUpdateListener.
+     * 
+     * @param listener the IIOReadUpdateListener to be removed.
+     */
+    public void removeIIOReadUpdateListener(IIOReadUpdateListener listener) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Removes registered IIOReadUpdateListeners.
+     */
+    public void removeAllIIOReadUpdateListeners() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the start of an sequence of image reads
+     * by calling the sequenceStarted method on all registered 
+     * IIOReadProgressListeners. 
+     * 
+     * @param minIndex the minimum index.
+     */
+    protected void processSequenceStarted(int minIndex) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the completion of an sequence of image reads
+     * by calling sequenceComplete method on all registered 
+     * IIOReadProgressListeners. 
+     */
+    protected void processSequenceComplete() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the start of an image read by calling the imageStarted
+     * method on all registered IIOReadProgressListeners.
+     * 
+     * @param imageIndex the image index.
+     */
+    protected void processImageStarted(int imageIndex) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the current percentage of image completion by calling 
+     * the imageProgress method on all registered IIOReadProgressListeners.
+     * 
+     * @param percentageDone the percentage done.
+     */
+    protected void processImageProgress(float percentageDone) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes image completion by calling the imageComplete method
+     * on all registered IIOReadProgressListeners. 
+     */
+    protected void processImageComplete() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the start of a thumbnail read by calling the
+     * thumbnailStarted method on all registered IIOReadProgressListeners. 
+     * 
+     * @param imageIndex the image index.
+     * @param thumbnailIndex the thumbnail index.
+     */
+    protected void processThumbnailStarted(int imageIndex, int thumbnailIndex) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the current percentage of thumbnail completion 
+     * by calling the thumbnailProgress method on all registered 
+     * IIOReadProgressListeners.
+     * 
+     * @param percentageDone the percentage done.
+     */
+    protected void processThumbnailProgress(float percentageDone) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the completion of a thumbnail read 
+     * by calling the thumbnailComplete method 
+     * on all registered IIOReadProgressListeners. 
+     */
+    protected void processThumbnailComplete() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes a read aborted event by calling the readAborted 
+     * method on all registered IIOReadProgressListeners.
+     */
+    protected void processReadAborted() {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the beginning of a progressive pass by calling 
+     * the passStarted method on all registered IIOReadUpdateListeners.
+     * 
+     * @param theImage the image to be updated.
+     * @param pass the current pass index.
+     * @param minPass the minimum pass index.
+     * @param maxPass the maximum pass index.
+     * @param minX the X coordinate of of the upper left pixel. 
+     * @param minY the Y coordinate of of the upper left pixel.
+     * @param periodX the horizontal separation between pixels.
+     * @param periodY the vertical separation between pixels.
+     * @param bands the number of affected bands.
+     */
+    protected void processPassStarted(BufferedImage theImage,
+                                  int pass,
+                                  int minPass,
+                                  int maxPass,
+                                  int minX,
+                                  int minY,
+                                  int periodX,
+                                  int periodY,
+                                  int[] bands) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the update of a set of samples by calling 
+     * the imageUpdate method on all registered IIOReadUpdateListeners.  
+     * 
+     * @param theImage the image to be updated.
+     * @param minX the X coordinate of the upper left pixel.
+     * @param minY the Y coordinate of the upper left pixel.
+     * @param width the width of updated area.
+     * @param height the height of updated area.
+     * @param periodX the horizontal separation between pixels.
+     * @param periodY the vertical separation between pixels.
+     * @param bands the number of affected bands.
+     */
+    protected void processImageUpdate(BufferedImage theImage,
+                                  int minX,
+                                  int minY,
+                                  int width,
+                                  int height,
+                                  int periodX,
+                                  int periodY,
+                                  int[] bands) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the end of a progressive pass by calling passComplete
+     * method of registered IIOReadUpdateListeners.
+     * 
+     * @param theImage the image to be updated.
+     */
+    protected void processPassComplete(BufferedImage theImage) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the beginning of a thumbnail progressive pass
+     * by calling the thumbnailPassStarted method on all 
+     * registered IIOReadUpdateListeners.
+     * 
+     * @param theThumbnail the the thumbnail to be updated.
+     * @param pass the current pass index.
+     * @param minPass the minimum pass index.
+     * @param maxPass the maximum pass index.
+     * @param minX the X coordinate of the upper left pixel. 
+     * @param minY the Y coordinate of the upper left pixel.
+     * @param periodX the horizontal separation between pixels.
+     * @param periodY the vertical separation between pixels.
+     * @param bands the number of affected bands.
+     */
+    protected void processThumbnailPassStarted(BufferedImage theThumbnail,
+                                           int pass,
+                                           int minPass,
+                                           int maxPass,
+                                           int minX,
+                                           int minY,
+                                           int periodX,
+                                           int periodY,
+                                           int[] bands) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the update of a set of samples in a thumbnail 
+     * image by calling the thumbnailUpdate method on all
+     * registered IIOReadUpdateListeners. 
+     * 
+     * @param theThumbnail the the thumbnail to be updated.
+     * @param minX the X coordinate of the upper left pixel. 
+     * @param minY the Y coordinate of the upper left pixel.
+     * @param periodX the horizontal separation between pixels.
+     * @param periodY the vertical separation between pixels.
+     * @param bands the number of affected bands.
+     */
+    protected void processThumbnailUpdate(BufferedImage theThumbnail,
+                                      int minX,
+                                      int minY,
+                                      int width,
+                                      int height,
+                                      int periodX,
+                                      int periodY,
+                                       int[] bands) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes the end of a thumbnail progressive pass 
+     * by calling the thumbnailPassComplete method
+     * on all registered IIOReadUpdateListeners. 
+     * 
+     * @param theThumbnail the thumbnail to be updated.
+     */
+    protected void processThumbnailPassComplete(BufferedImage theThumbnail) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes a warning message by calling warningOccurred method
+     * of registered IIOReadWarningListeners.
+     * 
+     * @param warning the warning.
+     */
+    protected void processWarningOccurred(String warning) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Processes a warning by calling the warningOccurred method 
+     * of on all registered IIOReadWarningListeners.
+     * 
+     * @param baseName the base name of ResourceBundles.
+     * @param keyword the keyword to index the warning among ResourceBundles.
+     */
+    protected void processWarningOccurred(String baseName, String keyword) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Resets this ImageReader.
+     */
+    public void reset() {
+        // def
+        setInput(null, false);
+        setLocale(null);
+        removeAllIIOReadUpdateListeners();
+        removeAllIIOReadWarningListeners();
+        removeAllIIOReadProgressListeners();
+        clearAbortRequest();
+    }
+
+    /**
+     * Disposes of any resources.
+     */
+    public void dispose() {
+        // do nothing by def
+    }
+
+    /**
+     * Gets the region of source image that should be read with the 
+     * specified width, height and ImageReadParam. 
+     * 
+     * @param param the ImageReadParam object, or null.
+     * @param srcWidth the source image's width.
+     * @param srcHeight the source image's  height.
+     * 
+     * @return the Rectangle of source region.
+     */
+    protected static Rectangle getSourceRegion(ImageReadParam param, int srcWidth, int srcHeight) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Computes the specified source region and the specified destination 
+     * region with the specified the width and height of the source image,
+     * an optional destination image, and an ImageReadParam. 
+     * 
+     * @param param the an ImageReadParam object, or null.
+     * @param srcWidth the source image's width.
+     * @param srcHeight the source image's height.
+     * @param image the destination image.
+     * @param srcRegion the source region.
+     * @param destRegion the destination region.
+     */
+    protected static void computeRegions(ImageReadParam param,
+                                     int srcWidth,
+                                     int srcHeight,
+                                     BufferedImage image,
+                                     Rectangle srcRegion,
+                                     Rectangle destRegion) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Checks the validity of the source and destination band and is called
+     * when the reader knows the number of bands of the source image and 
+     * the number of bands of the destination image. 
+     * 
+     * @param param the ImageReadParam for reading the Image.
+     * @param numSrcBands the number of bands in the source.
+     * @param numDstBands the number of bands in the destination.
+     */
+    protected static void checkReadParamBandSettings(ImageReadParam param,
+                                                 int numSrcBands,
+                                                 int numDstBands) {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    /**
+     * Gets the destination image where the decoded data is written. 
+     * 
+     * @param param the ImageReadParam.
+     * @param imageTypes the iterator of ImageTypeSpecifier objects.
+     * @param width the width of the image being decoded.
+     * @param height the height of the image being decoded.
+     * 
+     * @return the BufferedImage where decoded pixels should be written.
+     * 
+     * @throws IIOException the IIOException is thrown if 
+     * there is no suitable ImageTypeSpecifier.
+     */
+    protected static BufferedImage getDestination(ImageReadParam param, Iterator<ImageTypeSpecifier> imageTypes,
+                                              int width,
+                                              int height)
+                                       throws IIOException {
+        throw new UnsupportedOperationException("Not implemented yet");
+    }
+}
diff --git a/awt/javax/imageio/ImageTranscoder.java b/awt/javax/imageio/ImageTranscoder.java
new file mode 100644
index 0000000..1a0de76
--- /dev/null
+++ b/awt/javax/imageio/ImageTranscoder.java
@@ -0,0 +1,60 @@
+/*
+ *  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;
+
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.ImageTypeSpecifier;
+
+/**
+ * The ImageTranscoder interface is to be implemented by classes that
+ * perform image transcoding operations, that is, take images written
+ * in one format and write them in another format using
+ * read/write operations. Some image data can be lost in such processes.
+ * The ImageTranscoder interface converts metadata objects (IIOMetadata)
+ * of ImageReader to apropriate metadata object for ImageWriter.
+ */
+public interface ImageTranscoder {
+    
+    /**
+     * Converts the specified IIOMetadata object using the specified
+     * ImageWriteParam for obtaining writer's metadata structure.
+     * 
+     * @param inData the IIOMetadata.
+     * @param param the ImageWriteParam.
+     * 
+     * @return the IIOMetadata, or null.
+     */
+    IIOMetadata convertStreamMetadata(IIOMetadata inData, ImageWriteParam param);
+
+    /**
+     * Converts the specified IIOMetadata object using the specified
+     * ImageWriteParam for obtaining writer's metadata structure 
+     * and ImageTypeSpecifier object for obtaining the layout and 
+     * color information of the image for this metadata.
+     * 
+     * @param inData the IIOMetadata.
+     * @param imageType the ImageTypeSpecifier.
+     * @param param the ImageWriteParam.
+     * 
+     * @return the IIOMetadata, or null.
+     */
+    IIOMetadata convertImageMetadata(IIOMetadata inData, ImageTypeSpecifier imageType, ImageWriteParam param);
+}
diff --git a/awt/javax/imageio/ImageTypeSpecifier.java b/awt/javax/imageio/ImageTypeSpecifier.java
new file mode 100644
index 0000000..c93f269
--- /dev/null
+++ b/awt/javax/imageio/ImageTypeSpecifier.java
@@ -0,0 +1,339 @@
+/*
+ *  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;
+
+import java.awt.image.ColorModel;
+import java.awt.image.SampleModel;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+import java.awt.color.ColorSpace;
+
+/**
+ * The ImageTypeSpecifier class performs conversion operations
+ * on the SampleModel and the ColorModel of an image.
+ */
+public class ImageTypeSpecifier {
+    
+    /** 
+     * The ColorModel of this ImageTypeSpecifier.
+     */
+    protected ColorModel colorModel;
+    
+    /** 
+     * The SampleModel of this ImageTypeSpecifier. 
+     */
+    protected SampleModel sampleModel;
+
+    /**
+     * Instantiates a new ImageTypeSpecifier with the specified
+     * ColorModel and SampleModel objects.
+     * 
+     * @param colorModel the ColorModel.
+     * @param sampleModel the SampleModel.
+     */
+    public ImageTypeSpecifier(ColorModel colorModel, SampleModel sampleModel) {
+        if (colorModel == null) {
+            throw new IllegalArgumentException("color model should not be NULL");
+        }
+        if (sampleModel == null) {
+            throw new IllegalArgumentException("sample model should not be NULL");
+        }
+        if (!colorModel.isCompatibleSampleModel(sampleModel)) {
+            throw new IllegalArgumentException("color and sample models are not compatible");
+        }
+
+        this.colorModel = colorModel;
+        this.sampleModel = sampleModel;
+    }
+
+    /**
+     * Instantiates a new ImageTypeSpecifier using the specified 
+     * RenderedImage.
+     * 
+     * @param renderedImage the RenderedImage.
+     */
+    public ImageTypeSpecifier(RenderedImage renderedImage) {
+        if (renderedImage == null) {
+            throw new IllegalArgumentException("image should not be NULL");
+        }
+        this.colorModel = renderedImage.getColorModel();
+        this.sampleModel = renderedImage.getSampleModel();
+    }
+
+    /**
+     * Creates an ImageTypeSpecifier with the specified
+     * DirectColorModel and a packed SampleModel.
+     * 
+     * @param colorSpace the ColorSpace.
+     * @param redMask the red mask.
+     * @param greenMask the green mask.
+     * @param blueMask the blue mask.
+     * @param alphaMask the alpha mask.
+     * @param transferType the transfer type.
+     * @param isAlphaPremultiplied the parameter indicates
+     * if the color channel is premultiplied by alpha.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createPacked(ColorSpace colorSpace,
+                                                  int redMask,
+                                                  int greenMask,
+                                                  int blueMask,
+                                                  int alphaMask,
+                                                  int transferType,
+                                                  boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates an ImageTypeSpecifier with specified
+     * ComponentColorModel and a PixelInterleavedSampleModel.
+     * 
+     * @param colorSpace the ColorSpace.
+     * @param bandOffsets the band offsets.
+     * @param dataType the data type.
+     * @param hasAlpha the parameter indicates if alpha channel
+     * is needed.
+     * @param isAlphaPremultiplied the parameter indicates
+     * if the color channel is premultiplied by alpha.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createInterleaved(ColorSpace colorSpace,
+                                                       int[] bandOffsets,
+                                                       int dataType,
+                                                       boolean hasAlpha,
+                                                       boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+
+    /**
+     * Creates a ImageTypeSpecifier for a image with a 
+     * BandedSampleModel and a ComponentColorModel.
+     * 
+     * @param colorSpace the ColorSpace.
+     * @param bankIndices the bank indices.
+     * @param bandOffsets the band offsets.
+     * @param dataType the data type.
+     * @param hasAlpha the parameter indicates a presence of alpha channel.
+     * @param isAlphaPremultiplied the parameter indicates whether
+     * or not color channel is alpha premultiplied.
+     * 
+     * @return the image type specifier
+     */
+    public static ImageTypeSpecifier createBanded(ColorSpace colorSpace,
+                                                  int[] bankIndices,
+                                                  int[] bandOffsets,
+                                                  int dataType,
+                                                  boolean hasAlpha,
+                                                  boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates a ImageTypeSpecifier for a grayscale image.
+     * 
+     * @param bits the number of bits per gray value.
+     * @param dataType the data type.
+     * @param isSigned a signed flag.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createGrayscale(int bits,
+                                                     int dataType,
+                                                     boolean isSigned) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates a ImageTypeSpecifier for a grayscale image.
+     * 
+     * @param bits the number of bits per gray value.
+     * @param dataType the data type.
+     * @param isSigned a signed flag.
+     * @param isAlphaPremultiplied the parameter indicates
+     * if color channel is premultiplied by alpha, or not.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createGrayscale(int bits,
+                                                     int dataType,
+                                                     boolean isSigned,
+                                                     boolean isAlphaPremultiplied) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates a ImageTypeSpecifier with the indexed image format.
+     * 
+     * @param redLUT the red values of indecies.
+     * @param greenLUT the green values of indecies.
+     * @param blueLUT the blue values of indecies.
+     * @param alphaLUT the alpha values of indecies.
+     * @param bits the bits number for each index.
+     * @param dataType the data type.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createIndexed(byte[] redLUT,
+                                                   byte[] greenLUT,
+                                                   byte[] blueLUT,
+                                                   byte[] alphaLUT,
+                                                   int bits,
+                                                   int dataType) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates the ImageTypeSpecifier from 
+     * the specified buffered image type.
+     * 
+     * @param bufferedImageType the buffered image type.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createFromBufferedImageType(int bufferedImageType) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Creates the ImageTypeSpecifier from 
+     * the specified RenderedImage.
+     * 
+     * @param image the RenderedImage.
+     * 
+     * @return the ImageTypeSpecifier.
+     */
+    public static ImageTypeSpecifier createFromRenderedImage(RenderedImage image) {
+        if (null == image) {
+            throw new IllegalArgumentException("image should not be NULL");
+        }
+        return new ImageTypeSpecifier(image);
+    }
+
+    /**
+     * Gets the BufferedImage type.
+     * 
+     * @return the BufferedImage type.
+     */
+    public int getBufferedImageType() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the number of components.
+     * 
+     * @return the number of components
+     */
+    public int getNumComponents() {
+        return colorModel.getNumComponents();
+    }
+
+    /**
+     * Gets the number of bands.
+     * 
+     * @return the number of bands
+     */
+    public int getNumBands() {
+        return sampleModel.getNumBands();
+    }
+
+    /**
+     * Gets the number of bits per the specified band.
+     * 
+     * @param band the index of band.
+     * 
+     * @return the number of bits per the specified band.
+     */
+    public int getBitsPerBand(int band) {
+        if (band < 0 || band >= getNumBands()) {
+            throw new IllegalArgumentException();
+        }
+        return sampleModel.getSampleSize(band);
+    }
+
+    /**
+     * Gets the SampleModel associated with this ImageTypeSpecifier.
+     * 
+     * @return the SampleModel associated with this ImageTypeSpecifier.
+     */
+    public SampleModel getSampleModel() {
+        return sampleModel;
+    }
+
+    /**
+     * Gets a compatible SampleModel with the specified width and height.
+     * 
+     * @param width the width.
+     * @param height the height.
+     * 
+     * @return the SampleModel.
+     */
+    public SampleModel getSampleModel(int width, int height) {
+        if ((long)width*height > Integer.MAX_VALUE) {
+            throw new IllegalArgumentException("width * height > Integer.MAX_VALUE");
+        }
+        return sampleModel.createCompatibleSampleModel(width, height);
+    }
+
+    /**
+     * Gets the ColorModel associated with this ImageTypeSpecifier.
+     * 
+     * @return the ColorModel associated with this ImageTypeSpecifier. 
+     */
+    public ColorModel getColorModel() {
+        return colorModel;
+    }
+
+    /**
+     * Creates the BufferedImage with the specified width and height 
+     * and the ColorMadel and SampleModel which are specified by this 
+     * ImageTypeSpecifier.
+     * 
+     * @param width the width of the BufferedImage.
+     * @param height the height of the BufferedImage.
+     * 
+     * @return the BufferedImage.
+     */
+    public BufferedImage createBufferedImage(int width, int height) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Compares this ImageTypeSpecifier object with the specified 
+     * object.
+     * 
+     * @param o the Object to be compared.
+     * 
+     * @return true, if the object is an ImageTypeSpecifier with the same
+     * data as this ImageTypeSpecifier, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        boolean rt = false;
+        if (o instanceof ImageTypeSpecifier) {
+            ImageTypeSpecifier ts = (ImageTypeSpecifier) o;
+            rt = colorModel.equals(ts.colorModel) && sampleModel.equals(ts.sampleModel);
+        }
+        return rt;
+    }
+}
\ No newline at end of file
diff --git a/awt/javax/imageio/ImageWriteParam.java b/awt/javax/imageio/ImageWriteParam.java
new file mode 100644
index 0000000..d32fa59
--- /dev/null
+++ b/awt/javax/imageio/ImageWriteParam.java
@@ -0,0 +1,633 @@
+/*
+ *  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;
+
+import java.util.Locale;
+import java.awt.*;
+
+/**
+ * The ImageWriteParam class provides information to an ImageWriter 
+ * about how an image is to be encoded.
+ */
+public class ImageWriteParam extends IIOParam {
+
+    /** 
+     * The Constant MODE_DISABLED indicates that 
+     * stream is not tiled, progressive, or compressed.
+     */
+    public static final int MODE_DISABLED = 0;
+    
+    /** 
+     * The Constant MODE_DEFAULT indicates that the stream will be tiled, 
+     * progressive, or compressed according to the plug-in's default. 
+     */
+    public static final int MODE_DEFAULT = 1;
+    
+    /** 
+     * The Constant MODE_EXPLICIT indicates that the stream will be tiled,
+     * progressive, or compressed according to current settings
+     * which are defined by set methods. 
+     */
+    public static final int MODE_EXPLICIT = 2;
+    
+    /** 
+     * The Constant MODE_COPY_FROM_METADATA indicates that the stream
+     * will be tiled, progressive, or compressed according to
+     * stream or image metadata. 
+     */
+    public static final int MODE_COPY_FROM_METADATA = 3;
+    
+    /** Whether the ImageWriter can write tiles. */
+    protected boolean canWriteTiles = false;
+    
+    /** The tiling mode. */
+    protected int tilingMode = MODE_COPY_FROM_METADATA;
+    
+    /** The preferred tile sizes. */
+    protected Dimension[] preferredTileSizes = null;
+    
+    /** The tiling set. */
+    protected boolean tilingSet = false;
+    
+    /** The tile width. */
+    protected int tileWidth = 0;
+    
+    /** The tile height. */
+    protected int tileHeight = 0;
+    
+    /** Whether the ImageWriter can offset tiles. */
+    protected boolean canOffsetTiles = false;
+    
+    /** The tile grid x offset. */
+    protected int tileGridXOffset = 0;
+    
+    /** The tile grid y offset. */
+    protected int tileGridYOffset = 0;
+    
+    /** Whether the ImageWriter can write in progressive mode. */
+    protected boolean canWriteProgressive = false;
+    
+    /** The progressive mode. */
+    protected int progressiveMode = MODE_COPY_FROM_METADATA;
+    
+    /** Whether the ImageWriter can write in compressed mode. */
+    protected boolean canWriteCompressed = false;
+    
+    /** The compression mode. */
+    protected int compressionMode = MODE_COPY_FROM_METADATA;
+    
+    /** The compression types. */
+    protected String[] compressionTypes = null;
+    
+    /** The compression type. */
+    protected String compressionType = null;
+    
+    /** The compression quality. */
+    protected float compressionQuality = 1.0f;
+    
+    /** The locale. */
+    protected Locale locale = null;
+
+    /**
+     * Instantiates a new ImageWriteParam.
+     */
+    protected ImageWriteParam() {}
+
+    /**
+     * Instantiates a new ImageWriteParam with the specified Locale.
+     * 
+     * @param locale the Locale.
+     */
+    public ImageWriteParam(Locale locale) {
+        this.locale = locale;
+
+    }
+
+    /**
+     * Gets the mode for writing the stream in a progressive sequence. 
+     * 
+     * @return the current progressive mode.
+     */
+    public int getProgressiveMode() {
+        if (canWriteProgressive()) {
+            return progressiveMode;
+        }
+        throw new UnsupportedOperationException("progressive mode is not supported");
+    }
+
+    /**
+     * Returns true if images can be written using 
+     * increasing quality passes by progressive.  
+     * 
+     * @return true if images can be written using 
+     * increasing quality passes by progressive, false otherwise.
+     */
+    public boolean canWriteProgressive() {
+        return canWriteProgressive;
+    }
+
+    /**
+     * Sets the progressive mode which defines whether the stream 
+     * contains a progressive sequence of increasing quality
+     * during writing. The progressive mode should be one of
+     * the following values: MODE_DISABLED, MODE_DEFAULT, or
+     * MODE_COPY_FROM_METADATA.
+     * 
+     * @param mode the new progressive mode.
+     */
+    public void setProgressiveMode(int mode) {
+        if (canWriteProgressive()) {
+            if (mode < MODE_DISABLED || mode > MODE_COPY_FROM_METADATA || mode == MODE_EXPLICIT) {
+                throw new IllegalArgumentException("mode is not supported");
+            }
+            this.progressiveMode = mode;
+        }
+        throw new UnsupportedOperationException("progressive mode is not supported");
+    }
+
+    /**
+     * Returns true if the writer can use tiles with non zero 
+     * grid offsets while writing. 
+     * 
+     * @return true if the writer can use tiles with non zero 
+     * grid offsets while writing, false otherwise.
+     */
+    public boolean canOffsetTiles() {
+        return canOffsetTiles;
+    }
+
+    /**
+     * Returns true if this writer can write images with 
+     * compression.  
+     * 
+     * @return true, true if this writer can write images with 
+     * compression, false otherwise.
+     */
+    public boolean canWriteCompressed() {
+        return canWriteCompressed;
+    }
+
+    /**
+     * Returns true if the writer can write tiles.
+     * 
+     * @return true if the writer can write tiles, false otherwise.
+     */
+    public boolean canWriteTiles() {
+        return canWriteTiles;
+    }
+
+    /**
+     * Check write compressed.
+     */
+    private final void checkWriteCompressed() {
+        if (!canWriteCompressed()) {
+            throw new UnsupportedOperationException("Compression not supported.");
+        }
+    }
+
+    /**
+     * Check compression mode.
+     */
+    private final void checkCompressionMode() {
+        if (getCompressionMode() != MODE_EXPLICIT) {
+            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
+        }
+    }
+
+    /**
+     * Check compression type.
+     */
+    private final void checkCompressionType() {
+        if (getCompressionTypes() != null && getCompressionType() == null) {
+            throw new IllegalStateException("No compression type set!");
+        }
+    }
+
+    /**
+     * Gets the compression mode.
+     * 
+     * @return the compression mode if it's supported.
+     */
+    public int getCompressionMode() {
+        checkWriteCompressed();
+        return compressionMode;
+    }
+
+    /**
+     * Gets the an array of supported compression types.
+     * 
+     * @return the an array of supported compression types.
+     */
+    public String[] getCompressionTypes() {
+        checkWriteCompressed();
+        if (compressionTypes != null) {
+            return compressionTypes.clone();
+        }
+        return null;
+    }
+
+    /**
+     * Gets the current compression type, or returns null.
+     * 
+     * @return the current compression type, or returns null 
+     * if it is not set.
+     */
+    public String getCompressionType() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        return compressionType;
+    }
+
+    /**
+     * Gets a bit rate which represents an estimate of the number of bits 
+     * of output data for each bit of input image data with the specified 
+     * quality.
+     * 
+     * @param quality the quality.
+     * 
+     * @return an estimate of the bit rate, or -1.0F if there is no 
+     * estimate. 
+     */
+    public float getBitRate(float quality) {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        if (quality < 0 || quality > 1) {
+            throw new IllegalArgumentException("Quality out-of-bounds!");
+        }
+        return -1.0f;
+    }
+
+    /**
+     * Gets the compression quality.
+     * 
+     * @return the compression quality.
+     */
+    public float getCompressionQuality() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return compressionQuality;
+    }
+
+    /**
+     * Gets the array of compression quality descriptions.
+     * 
+     * @return the string array of compression quality descriptions.
+     */
+    public String[] getCompressionQualityDescriptions() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return null;
+    }
+
+    /**
+     * Gets an array of floats which decribe 
+     * compression quality levels. 
+     * 
+     * @return the array of compression quality values.
+     */
+    public float[] getCompressionQualityValues() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return null;
+    }
+
+    /**
+     * Gets the locale of this ImageWriteParam.
+     * 
+     * @return the locale of this ImageWriteParam.
+     */
+    public Locale getLocale() {
+        return locale;
+    }
+
+    /**
+     * Gets the current compression type using the current Locale. 
+     * 
+     * @return the current compression type using the current Locale.
+     */
+    public String getLocalizedCompressionTypeName() {
+        checkWriteCompressed();
+        checkCompressionMode();
+
+        String compressionType = getCompressionType();
+        if (compressionType == null) {
+            throw new IllegalStateException("No compression type set!");
+        }
+        return compressionType;
+
+    }
+
+    /**
+     * Check tiling.
+     */
+    private final void checkTiling() {
+        if (!canWriteTiles()) {
+            throw new UnsupportedOperationException("Tiling not supported!");
+        }
+    }
+
+    /**
+     * Check tiling mode.
+     */
+    private final void checkTilingMode() {
+        if (getTilingMode() != MODE_EXPLICIT) {
+            throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
+        }
+    }
+
+    /**
+     * Check tiling params.
+     */
+    private final void checkTilingParams() {
+        if (!tilingSet) {
+            throw new IllegalStateException("Tiling parameters not set!");
+        }
+    }
+
+    /**
+     * Gets the tiling mode if tiling is supported.
+     * 
+     * @return the tiling mode if tiling is supported.
+     */
+    public int getTilingMode() {
+        checkTiling();
+        return tilingMode;
+    }
+
+    /**
+     * Gets an array of Dimensions giving the sizes of the tiles as 
+     * they are encoded in the output file or stream. 
+     * 
+     * @return the preferred tile sizes.
+     */
+    public Dimension[] getPreferredTileSizes() {
+        checkTiling();
+        if (preferredTileSizes == null) {
+            return null;
+        }
+
+        Dimension[] retval = new Dimension[preferredTileSizes.length];
+        for (int i = 0; i < preferredTileSizes.length; i++) {
+            retval[i] = new Dimension(retval[i]);
+        }
+        return retval;
+    }
+
+    /**
+     * Gets the tile grid X offset for encoding.
+     * 
+     * @return the tile grid X offset for encoding.
+     */
+    public int getTileGridXOffset() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileGridXOffset;
+    }
+
+    /**
+     * Gets the tile grid Y offset for encoding.
+     * 
+     * @return the tile grid Y offset for encoding.
+     */
+    public int getTileGridYOffset() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileGridYOffset;
+    }
+
+    /**
+     * Gets the tile height in an image as it is written to the 
+     * output stream.
+     * 
+     * @return the tile height in an image as it is written to the 
+     * output stream.
+     */
+    public int getTileHeight() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileHeight;
+    }
+
+    /**
+     * Gets the tile width in an image as it is written to the 
+     * output stream.
+     * 
+     * @return the tile width in an image as it is written to the 
+     * output stream.
+     */
+    public int getTileWidth() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileWidth;
+    }
+
+    /**
+     * Checks if the current compression type has lossless 
+     * compression or not. 
+     * 
+     * @return true, if the current compression type has lossless 
+     * compression, false otherwise.
+     */
+    public boolean isCompressionLossless() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return true;
+    }
+
+    /**
+     * Removes current compression type.
+     */
+    public void unsetCompression() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        compressionType = null;
+        compressionQuality = 1;
+    }
+
+    /**
+     * Sets the compression mode to the specified value.
+     * The specified mode can be one of the predefined
+     * constants: MODE_DEFAULT, MODE_DISABLED, MODE_EXPLICIT, 
+     * or MODE_COPY_FROM_METADATA.
+     *  
+     * @param mode the new compression mode to be set.
+     */
+    public void setCompressionMode(int mode) {
+        checkWriteCompressed();
+        switch (mode) {
+            case MODE_EXPLICIT: {
+                compressionMode = mode;
+                unsetCompression();
+                break;
+            }
+            case MODE_COPY_FROM_METADATA:
+            case MODE_DISABLED:
+            case MODE_DEFAULT: {
+                compressionMode = mode;
+                break;
+            }
+            default: {
+                throw new IllegalArgumentException("Illegal value for mode!");
+            }
+        }
+    }
+
+    /**
+     * Sets the compression quality. The value should be between 0 and 1.
+     * 
+     * @param quality the new compression quality, 
+     * float value between 0 and 1. 
+     */
+    public void setCompressionQuality(float quality) {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        if (quality < 0 || quality > 1) {
+            throw new IllegalArgumentException("Quality out-of-bounds!");
+        }
+        compressionQuality = quality;
+    }
+
+    /**
+     * Sets the compression type. The specified string
+     * should be one of the values returned 
+     * by getCompressionTypes method.
+     * 
+     * @param compressionType the new compression type.
+     */
+    public void setCompressionType(String compressionType) {
+        checkWriteCompressed();
+        checkCompressionMode();
+
+        if (compressionType == null) { // Don't check anything
+            this.compressionType = null;
+        } else {
+            String[] compressionTypes = getCompressionTypes();
+            if (compressionTypes == null) {
+                throw new UnsupportedOperationException("No settable compression types");
+            }
+
+            for (int i = 0; i < compressionTypes.length; i++) {
+                if (compressionTypes[i].equals(compressionType)) {
+                    this.compressionType = compressionType;
+                    return;
+                }
+            }
+
+            // Compression type is not in the list.
+            throw new IllegalArgumentException("Unknown compression type!");
+        }
+    }
+
+    /**
+     * Sets the instruction that tiling should be performed for 
+     * the image in the output stream with the specified parameters. 
+     * 
+     * @param tileWidth the tile's width.
+     * @param tileHeight the tile's height.
+     * @param tileGridXOffset the tile grid's x offset.
+     * @param tileGridYOffset the tile grid's y offset.
+     */
+    public void setTiling(int tileWidth, int tileHeight, int tileGridXOffset, int tileGridYOffset) {
+        checkTiling();
+        checkTilingMode();
+
+        if (!canOffsetTiles() && (tileGridXOffset != 0 || tileGridYOffset != 0)) {
+            throw new UnsupportedOperationException("Can't offset tiles!");
+        }
+
+        if (tileWidth <=0 || tileHeight <= 0) {
+            throw new IllegalArgumentException("tile dimensions are non-positive!");
+        }
+
+        Dimension preferredTileSizes[] = getPreferredTileSizes();
+        if (preferredTileSizes != null) {
+            for (int i = 0; i < preferredTileSizes.length; i+=2) {
+                Dimension minSize = preferredTileSizes[i];
+                Dimension maxSize = preferredTileSizes[i+1];
+                if (
+                        tileWidth < minSize.width || tileWidth > maxSize.width ||
+                        tileHeight < minSize.height || tileHeight > maxSize.height
+                ) {
+                    throw new IllegalArgumentException("Illegal tile size!");
+                }
+            }
+        }
+
+        tilingSet = true;
+        this.tileWidth = tileWidth;
+        this.tileHeight = tileHeight;
+        this.tileGridXOffset = tileGridXOffset;
+        this.tileGridYOffset = tileGridYOffset;
+    }
+
+    /**
+     * Clears all tiling settings.
+     */
+    public void unsetTiling() {
+        checkTiling();
+        checkTilingMode();
+
+        tilingSet = false;
+        tileWidth = 0;
+        tileHeight = 0;
+        tileGridXOffset = 0;
+        tileGridYOffset = 0;
+    }
+
+    /**
+     * Sets the tiling mode. The specified mode should be one of the 
+     * following values: MODE_DISABLED, MODE_DEFAULT, MODE_EXPLICIT,
+     * or MODE_COPY_FROM_METADATA.
+     * 
+     * @param mode the new tiling mode.
+     */
+    public void setTilingMode(int mode) {
+        checkTiling();
+
+        switch (mode) {
+            case MODE_EXPLICIT: {
+                tilingMode = mode;
+                unsetTiling();
+                break;
+            }
+            case MODE_COPY_FROM_METADATA:
+            case MODE_DISABLED:
+            case MODE_DEFAULT: {
+                tilingMode = mode;
+                break;
+            }
+            default: {
+                throw new IllegalArgumentException("Illegal value for mode!");
+            }
+        }
+    }
+}
+
diff --git a/awt/javax/imageio/ImageWriter.java b/awt/javax/imageio/ImageWriter.java
new file mode 100644
index 0000000..d6119b0
--- /dev/null
+++ b/awt/javax/imageio/ImageWriter.java
@@ -0,0 +1,951 @@
+/*
+ *  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;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.imageio.event.IIOWriteProgressListener;
+import javax.imageio.event.IIOWriteWarningListener;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageWriterSpi;
+
+/**
+ * The ImageWriter class is an abstract class for encoding images.
+ * ImageWriter objects are instantiated by the service provider 
+ * interface, ImageWriterSpi class, for the specific format. 
+ * ImageWriterSpi class should be registered with the IIORegistry, 
+ * which uses them for format recognition and presentation of available 
+ * format readers and writers.
+ */
+public abstract class ImageWriter implements ImageTranscoder {
+
+    /** The available locales. */
+    protected Locale[] availableLocales;
+    
+    /** The locale. */
+    protected Locale locale;
+    
+    /** The originating provider. */
+    protected ImageWriterSpi originatingProvider;
+    
+    /** The output. */
+    protected Object output;
+    
+    /** The progress listeners. */
+    protected List<IIOWriteProgressListener> progressListeners;
+    
+    /** The warning listeners. */
+    protected List<IIOWriteWarningListener> warningListeners;
+    
+    /** The warning locales. */
+    protected List<Locale> warningLocales;
+
+    // Indicates that abort operation is requested
+    // Abort mechanism should be thread-safe
+    /** The aborted. */
+    private boolean aborted;
+
+    /**
+     * Instantiates a new ImageWriter.
+     * 
+     * @param originatingProvider the ImageWriterSpi which 
+     * instanties this ImageWriter.
+     */
+    protected ImageWriter(ImageWriterSpi originatingProvider) {
+        this.originatingProvider = originatingProvider;
+    }
+
+    public abstract IIOMetadata convertStreamMetadata(IIOMetadata iioMetadata,
+                                             ImageWriteParam imageWriteParam);
+
+    public abstract IIOMetadata convertImageMetadata(IIOMetadata iioMetadata,
+                                            ImageTypeSpecifier imageTypeSpecifier,
+                                            ImageWriteParam imageWriteParam);
+
+    /**
+     * Gets the ImageWriterSpi which instantiated this ImageWriter. 
+     * 
+     * @return the ImageWriterSpi.
+     */
+    public ImageWriterSpi getOriginatingProvider() {
+        return originatingProvider;
+    }
+
+    /**
+     * Processes the start of an image read by calling their imageStarted
+     * method of registered IIOWriteProgressListeners.
+     * 
+     * @param imageIndex the image index.
+     */
+    protected void processImageStarted(int imageIndex) {
+        if (null != progressListeners) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.imageStarted(this, imageIndex);
+            }
+        }
+    }
+
+    /**
+     * Processes the current percentage of image completion by calling 
+     * imageProgress method of registered IIOWriteProgressListener.
+     * 
+     * @param percentageDone the percentage done.
+     */
+    protected void processImageProgress(float percentageDone) {
+        if (null != progressListeners) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.imageProgress(this, percentageDone);
+            }
+        }
+    }
+
+    /**
+     * Processes image completion by calling imageComplete method
+     * of registered IIOWriteProgressListeners. 
+     */
+    protected void processImageComplete() {
+        if (null != progressListeners) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.imageComplete(this);
+            }
+        }
+    }
+
+    /**
+     * Processes a warning message by calling warningOccurred method
+     * of registered IIOWriteWarningListeners.
+     * 
+     * @param imageIndex the image index.
+     * @param warning the warning.
+     */
+    protected void processWarningOccurred(int imageIndex, String warning) {
+        if (null == warning) {
+            throw new NullPointerException("warning message should not be NULL");
+        }
+        if (null != warningListeners) {
+            for (IIOWriteWarningListener listener : warningListeners) {
+                listener.warningOccurred(this, imageIndex, warning);
+            }
+        }
+    }
+
+    /**
+     * Processes a warning message by calling warningOccurred method
+     * of registered IIOWriteWarningListeners with string from 
+     * ResourceBundle.
+     * 
+     * @param imageIndex the image index.
+     * @param bundle the name of ResourceBundle.
+     * @param key the keyword.
+     */
+    protected void processWarningOccurred(int imageIndex, String bundle, String key) {
+        if (warningListeners != null) { // Don't check the parameters
+            return;
+        }
+
+        if (bundle == null) {
+            throw new IllegalArgumentException("baseName == null!");
+        }
+        if (key == null) {
+            throw new IllegalArgumentException("keyword == null!");
+        }
+
+        // Get the context class loader and try to locate the bundle with it first
+        ClassLoader contextClassloader = AccessController.doPrivileged(
+                new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
+                        return Thread.currentThread().getContextClassLoader();
+                    }
+        });
+
+        // Iterate through both listeners and locales
+        int n = warningListeners.size();
+        for (int i=0; i < n; i++) {
+            IIOWriteWarningListener listener = warningListeners.get(i);
+            Locale locale = warningLocales.get(i);
+
+            // Now try to get the resource bundle
+            ResourceBundle rb;
+            try {
+                rb = ResourceBundle.getBundle(bundle, locale, contextClassloader);
+            } catch (MissingResourceException e) {
+                try {
+                    rb = ResourceBundle.getBundle(bundle, locale);
+                } catch (MissingResourceException e1) {
+                    throw new IllegalArgumentException("Bundle not found!");
+                }
+            }
+
+            try {
+                String warning = rb.getString(key);
+                listener.warningOccurred(this, imageIndex, warning);
+            } catch (MissingResourceException e) {
+                throw new IllegalArgumentException("Resource is missing!");
+            } catch (ClassCastException e) {
+                throw new IllegalArgumentException("Resource is not a String!");
+            }
+        }
+    }
+
+    /**
+     * Sets the specified Object to the output of this ImageWriter. 
+     * 
+     * @param output the Object which represents destination, it can 
+     * be ImageOutputStream or other objects.
+     */
+    public void setOutput(Object output) {
+        if (output != null) {
+            ImageWriterSpi spi = getOriginatingProvider();
+            if (null != spi) {
+                Class[] outTypes = spi.getOutputTypes();
+                boolean supported = false;
+                for (Class<?> element : outTypes) {
+                    if (element.isInstance(output)) {
+                        supported = true;
+                        break;
+                    }
+                }
+                if (!supported) {
+                    throw new IllegalArgumentException("output " + output + " is not supported");
+                }
+            }
+        }
+        this.output = output;
+    }
+
+    /**
+     * Writes a completed image stream that contains the specified image, 
+     * default metadata, and thumbnails to the output.
+     * 
+     * @param image the specified image to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred
+     * during writting.
+     */
+    public void write(IIOImage image) throws IOException {
+        write(null, image, null);
+    }
+
+    /**
+     * Writes a completed image stream that contains the specified 
+     * rendered image, default metadata, and thumbnails to the output.
+     * 
+     * @param image the specified RenderedImage to be written.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred
+     * during writting.
+     */
+    public void write(RenderedImage image) throws IOException {
+        write(null, new IIOImage(image, null, null), null);
+    }
+
+    /**
+     * Writes a completed image stream that contains the specified image,
+     * metadata and thumbnails to the output.
+     * 
+     * @param streamMetadata the stream metadata, or null.
+     * @param image the specified image to be written, if
+     * canWriteRaster() method returns false, then Image must contain 
+     * only RenderedImage.
+     * @param param the ImageWriteParam, or null.
+     * 
+     * @throws IOException - if an error occurs during writing.
+     */
+    public abstract void write(IIOMetadata streamMetadata,
+                               IIOImage image, ImageWriteParam param) throws IOException;
+
+    /**
+     * Disposes of any resources.
+     */
+    public void dispose() {
+        // def impl. does nothing according to the spec.
+    }
+
+    /**
+     * Requests an abort operation for current writing operation. 
+     */
+    public synchronized void abort() {
+        aborted = true;
+    }
+
+    /**
+     * Checks whether or not a request to abort the current write operation 
+     * has been made successfully.
+     * 
+     * @return true, if the request to abort the current write operation 
+     * has been made successfully, false otherwise.
+     */
+    protected synchronized boolean abortRequested() {
+        return aborted;
+    }
+
+    /**
+     * Clears all previous abort request, and abortRequested returns false
+     * after calling this method.
+     */
+    protected synchronized void clearAbortRequest() {
+        aborted = false;
+    }
+
+    /**
+     * Adds the IIOWriteProgressListener listener.
+     * 
+     * @param listener the IIOWriteProgressListener listener.
+     */
+    public void addIIOWriteProgressListener(IIOWriteProgressListener listener) {
+        if (listener == null) {
+            return;
+        }
+
+        if (progressListeners == null) {
+            progressListeners = new ArrayList<IIOWriteProgressListener>();
+        }
+
+        progressListeners.add(listener);
+    }
+
+    /**
+     * Adds the IIOWriteWarningListener.
+     * 
+     * @param listener the IIOWriteWarningListener listener.
+     */
+    public void addIIOWriteWarningListener(IIOWriteWarningListener listener) {
+        if (listener == null) {
+            return;
+        }
+
+        if (warningListeners == null) {
+            warningListeners = new ArrayList<IIOWriteWarningListener>();
+            warningLocales = new ArrayList<Locale>();
+        }
+
+        warningListeners.add(listener);
+        warningLocales.add(getLocale());
+    }
+
+    /**
+     * Gets the output object that was set by setOutput method.
+     * 
+     * @return the output object such as ImageOutputStream, or null if
+     * it is not set.
+     */
+    public Object getOutput() {
+        return output;
+    }
+
+    /**
+     * Check output return false.
+     * 
+     * @return true, if successful
+     */
+    private final boolean checkOutputReturnFalse() {
+        if (getOutput() == null) {
+            throw new IllegalStateException("getOutput() == null!");
+        }
+        return false;
+    }
+
+    /**
+     * Unsupported operation.
+     */
+    private final void unsupportedOperation() {
+        if (getOutput() == null) {
+            throw new IllegalStateException("getOutput() == null!");
+        }
+        throw new UnsupportedOperationException("Unsupported write variant!");
+    }
+
+
+    /**
+     * Returns true if a new empty image can be inserted at 
+     * the specified index. 
+     * 
+     * @param imageIndex the specified index of image.
+     * 
+     * @return true if a new empty image can be inserted at 
+     * the specified index, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canInsertEmpty(int imageIndex) throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if a new image can be inserted at the specified index. 
+     * 
+     * @param imageIndex the specified index of image.
+     * 
+     * @return true if a new image can be inserted at the specified index, 
+     * false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canInsertImage(int imageIndex) throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returnes true if the image with the specified index can be removed.
+     * 
+     * @param imageIndex the specified index of image.
+     * 
+     * @return true if the image with the specified index can be removed,
+     * false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canRemoveImage(int imageIndex) throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if metadata of the image with the specified index
+     * can be replaced.
+     * 
+     * @param imageIndex the specified image index.
+     * 
+     * @return true if metadata of the image with the specified index
+     * can be replaced, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canReplaceImageMetadata(int imageIndex) throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if pixels of the image with the specified index 
+     * can be replaced by the replacePixels  methods.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @return true if pixels of the image with the specified index 
+     * can be replaced by the replacePixels  methods, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canReplacePixels(int imageIndex) throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if the stream metadata presented in the output
+     * can be removed.
+     * 
+     * @return true if the stream metadata presented in the output
+     * can be removed, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canReplaceStreamMetadata() throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if the writing of a complete image stream which
+     * contains a single image is supported with undefined pixel 
+     * values and associated metadata and thumbnails to the output. 
+     * 
+     * @return true if the writing of a complete image stream which
+     * contains a single image is supported, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public boolean canWriteEmpty() throws IOException {
+        return checkOutputReturnFalse();
+    }
+
+    /**
+     * Returns true if the methods which taken an IIOImageParameter 
+     * can deal with a Raster source image.
+     * 
+     * @return true if the methods which taken an IIOImageParameter 
+     * can deal with a Raster source image, false otherwise.
+     */
+    public boolean canWriteRasters() {
+        return false;
+    }
+
+    /**
+     * Returns true if the writer can add an image to stream that
+     * already contains header information.
+     * 
+     * @return if the writer can add an image to stream that
+     * already contains header information, false otherwise.
+     */
+    public boolean canWriteSequence() {
+        return false;
+    }
+
+    /**
+     * Ends the insertion of a new image.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void endInsertEmpty() throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Ends the repalce pixels operation.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void endReplacePixels() throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Ends an empty write operation.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void endWriteEmpty() throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Ends the sequence of write operations.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void endWriteSequence() throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Gets an array of available locales.
+     * 
+     * @return an of array available locales.
+     */
+    public Locale[] getAvailableLocales() {
+        if (availableLocales == null) {
+            return null;
+        }
+
+        return availableLocales.clone();
+    }
+
+    /**
+     * Gets an IIOMetadata object that contains default values 
+     * for encoding an image with the specified type. 
+     * 
+     * @param imageType the ImageTypeSpecifier.
+     * @param param the ImageWriteParam.
+     * 
+     * @return the IIOMetadata object.
+     */
+    public abstract IIOMetadata getDefaultImageMetadata(
+            ImageTypeSpecifier imageType,
+            ImageWriteParam param
+    );
+
+    /**
+     * Gets an IIOMetadata object that contains default values 
+     * for encoding a stream of images.
+     * 
+     * @param param the ImageWriteParam.
+     * 
+     * @return the IIOMetadata object.
+     */
+    public abstract IIOMetadata getDefaultStreamMetadata(ImageWriteParam param);
+
+    /**
+     * Gets the current locale of this ImageWriter.
+     * 
+     * @return the current locale of this ImageWriter.
+     */
+    public Locale getLocale() {
+        return locale;
+    }
+
+    /**
+     * Gets the default write param.
+     * Gets a new ImageWriteParam object for this ImageWriter with the
+     * current Locale.
+     * 
+     * @return a new ImageWriteParam object for this ImageWriter.
+     */
+    public ImageWriteParam getDefaultWriteParam() {
+        return new ImageWriteParam(getLocale());
+    }
+
+    /**
+     * Gets the number of thumbnails suported by the format 
+     * being written with supported image type, image write 
+     * parameters, stream, and image metadata objects.
+     * 
+     * @param imageType the ImageTypeSpecifier.
+     * @param param the image's parameters.
+     * @param streamMetadata the stream metadata.
+     * @param imageMetadata the image metadata.
+     * 
+     * @return the number of thumbnails supported
+     */
+    public int getNumThumbnailsSupported(
+            ImageTypeSpecifier imageType,
+            ImageWriteParam param,
+            IIOMetadata streamMetadata,
+            IIOMetadata imageMetadata
+    ) {
+        return 0;
+    }
+
+    /**
+     * Gets the preferred thumbnail sizes.
+     * Gets an array of Dimensions with the sizes for thumbnail images 
+     * as they are encoded in the output file or stream. 
+     * 
+     * @param imageType the ImageTypeSpecifier.
+     * @param param the ImageWriteParam.
+     * @param streamMetadata the stream metadata.
+     * @param imageMetadata the image metadata.
+     * 
+     * @return the preferred thumbnail sizes
+     */
+    public Dimension[] getPreferredThumbnailSizes(
+            ImageTypeSpecifier imageType,
+            ImageWriteParam param,
+            IIOMetadata streamMetadata,
+            IIOMetadata imageMetadata
+    ) {
+        return null;
+    }
+
+    /**
+     * Prepares insertion of an empty image by requesting the insertion of 
+     * a new image into an existing image stream.
+     * 
+     * @param imageIndex the image index.
+     * @param imageType the image type.
+     * @param width the width of the image.
+     * @param height the height of the image.
+     * @param imageMetadata the image metadata, or null.
+     * @param thumbnails the array thumbnails for this image, or null.
+     * @param param the ImageWriteParam, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void prepareInsertEmpty(
+            int imageIndex, ImageTypeSpecifier imageType,
+            int width, int height,
+            IIOMetadata imageMetadata, List<? extends BufferedImage> thumbnails,
+            ImageWriteParam param
+    ) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Prepares the writer to call the replacePixels method for the
+     * specified region. 
+     * 
+     * @param imageIndex the image's index.
+     * @param region the specified region.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void prepareReplacePixels(int imageIndex, Rectangle region) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Prepares the writer for writing an empty image by beginning the 
+     * process of writing a complete image stream that contains a single image 
+     * with undefined pixel values, metadata and thumbnails, 
+     * to the output. 
+     * 
+     * @param streamMetadata the stream metadata.
+     * @param imageType the image type.
+     * @param width the width of the image.
+     * @param height the height of the image.
+     * @param imageMetadata the image's metadata, or null.
+     * @param thumbnails the image's thumbnails, or null.
+     * @param param the image's parameters, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void prepareWriteEmpty(
+            IIOMetadata streamMetadata, ImageTypeSpecifier imageType,
+            int width, int height,
+            IIOMetadata imageMetadata, List<? extends BufferedImage> thumbnails,
+            ImageWriteParam param
+    ) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Prepares a stream to accept calls of writeToSequence method 
+     * using the metadata object. 
+     * 
+     * @param streamMetadata the stream metadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void prepareWriteSequence(IIOMetadata streamMetadata) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Processes the completion of a thumbnail read 
+     * by calling their thumbnailComplete method 
+     * of registered IIOWriteProgressListeners. 
+     */
+    protected void processThumbnailComplete() {
+        if (progressListeners != null) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.thumbnailComplete(this);
+            }
+        }
+    }
+
+    /**
+     * Processes the current percentage of thumbnail completion 
+     * by calling their thumbnailProgress method of registered 
+     * IIOWriteProgressListeners.
+     * 
+     * @param percentageDone the percentage done.
+     */
+    protected void processThumbnailProgress(float percentageDone) {
+        if (progressListeners != null) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.thumbnailProgress(this, percentageDone);
+            }
+        }
+    }
+
+    /**
+     * Processes the start of a thumbnail read by calling 
+     * thumbnailStarted method of registered IIOWriteProgressListeners. 
+     * 
+     * @param imageIndex the image index.
+     * @param thumbnailIndex the thumbnail index.
+     */
+    protected void processThumbnailStarted(int imageIndex, int thumbnailIndex) {
+        if (progressListeners != null) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
+            }
+        }
+    }
+
+    /**
+     * Processes that the writing has been aborted by calling writeAborted 
+     * method of registered IIOWriteProgressListeners.
+     */
+    protected void processWriteAborted() {
+        if (progressListeners != null) {
+            for (IIOWriteProgressListener listener : progressListeners) {
+                listener.writeAborted(this);
+            }
+        }
+    }
+
+    /**
+     * Removes the all IIOWriteProgressListener listeners.
+     */
+    public void removeAllIIOWriteProgressListeners() {
+        progressListeners = null;
+    }
+
+    /**
+     * Removes the all IIOWriteWarningListener listeners.
+     */
+    public void removeAllIIOWriteWarningListeners() {
+        warningListeners = null;
+        warningLocales = null;
+    }
+
+    /**
+     * Removes the specified IIOWriteProgressListener listener.
+     * 
+     * @param listener the registered IIOWriteProgressListener 
+     * to be removed.
+     */
+    public void removeIIOWriteProgressListener(IIOWriteProgressListener listener) {
+        if (progressListeners != null && listener != null) {
+            if (progressListeners.remove(listener) && progressListeners.isEmpty()) {
+                progressListeners = null;
+            }
+        }
+    }
+
+    /**
+     * Removes the specified IIOWriteWarningListener listener.
+     * 
+     * @param listener the registered IIOWriteWarningListener listener
+     * to be removed.
+     */
+    public void removeIIOWriteWarningListener(IIOWriteWarningListener listener) {
+        if (warningListeners == null || listener == null) {
+            return;
+        }
+
+        int idx = warningListeners.indexOf(listener);
+        if (idx > -1) {
+            warningListeners.remove(idx);
+            warningLocales.remove(idx);
+
+            if (warningListeners.isEmpty()) {
+                warningListeners = null;
+                warningLocales = null;
+            }
+        }
+    }
+
+    /**
+     * Removes the image with the specified index from the stream.
+     * 
+     * @param imageIndex the image's index.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void removeImage(int imageIndex) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Replaces image metadata of the image with specified index.
+     * 
+     * @param imageIndex the image's index.
+     * @param imageMetadata the image metadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void replaceImageMetadata(int imageIndex, IIOMetadata imageMetadata) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Replaces a part of an image presented in the output
+     * with the specified RenderedImage.
+     * 
+     * @param image the RenderedImage.
+     * @param param the ImageWriteParam.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void replacePixels(RenderedImage image, ImageWriteParam param) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Replaces a part of an image presented in the output
+     * with the specified Raster.
+     * 
+     * @param raster the Raster.
+     * @param param the ImageWriteParam.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void replacePixels(Raster raster, ImageWriteParam param) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Replaces the stream metadata of the output with new IIOMetadata.
+     * 
+     * @param streamMetadata the new stream metadata.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void replaceStreamMetadata(IIOMetadata streamMetadata) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Sets the locale of this ImageWriter.
+     * 
+     * @param locale the new locale.
+     */
+    public void setLocale(Locale locale) {
+        if (locale == null) {
+            this.locale = null;
+            return;
+        }
+
+        Locale[] locales = getAvailableLocales();
+        boolean validLocale = false;
+        if (locales != null) {
+            for (int i = 0; i < locales.length; i++) {
+                if (locale.equals(locales[i])) {
+                    validLocale = true;
+                    break;
+                }
+            }
+        }
+
+        if (validLocale) {
+            this.locale = locale;
+        } else {
+            throw new IllegalArgumentException("Invalid locale!");
+        }
+    }
+
+    /**
+     * Resets this ImageWriter.
+     */
+    public void reset() {
+        setOutput(null);
+        setLocale(null);
+        removeAllIIOWriteWarningListeners();
+        removeAllIIOWriteProgressListeners();
+        clearAbortRequest();
+    }
+
+    /**
+     * Inserts image into existing output stream. 
+     * 
+     * @param imageIndex the image index where an image will be written.
+     * @param image the specified image to be written.
+     * @param param the ImageWriteParam, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public void writeInsert(int imageIndex, IIOImage image, ImageWriteParam param) throws IOException {
+        unsupportedOperation();
+    }
+
+    /**
+     * Writes the specified image to the sequence.
+     * 
+     * @param image the image to be written.
+     * @param param the ImageWriteParam, or null.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred 
+     * during writting.
+     */
+    public void writeToSequence(IIOImage image, ImageWriteParam param) throws IOException {
+        unsupportedOperation();
+    }
+}
diff --git a/awt/javax/imageio/event/IIOReadProgressListener.java b/awt/javax/imageio/event/IIOReadProgressListener.java
new file mode 100644
index 0000000..3d65807
--- /dev/null
+++ b/awt/javax/imageio/event/IIOReadProgressListener.java
@@ -0,0 +1,103 @@
+/*
+ *  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.event;
+
+import java.util.EventListener;
+import javax.imageio.ImageReader;
+
+/**
+ * The IIOReadProgressListener interface notifies callers 
+ * about the progress of the image and thumbnail reading methods.
+ */
+public interface IIOReadProgressListener extends EventListener {
+
+    /**
+     * Notifies this listener that the image reading has been completed. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     */
+    void imageComplete(ImageReader source);
+    
+    /**
+     * Notifies this listener about the degree of completion of the read call.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param percentageDone the percentage of decoding done.
+     */
+    void imageProgress(ImageReader source, float percentageDone);
+    
+    /**
+     * Notifies this listener that an image read operation has been started. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param imageIndex the index of the image in an input file or 
+     * stream to be read.
+     */
+    void imageStarted(ImageReader source, int imageIndex);
+    
+    /**
+     * Notifies this listener that a read operation has been aborted.
+     * 
+     * @param source the ImageReader object which calls this method.
+     */
+    void readAborted(ImageReader source);
+    
+    /**
+     * Notifies this listener that a sequence of read operations has been completed. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     */
+    void sequenceComplete(ImageReader source);
+    
+    /**
+     * Notifies this listener that a sequence of read operation has been started. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param minIndex the index of the first image to be read.
+     */
+    void sequenceStarted(ImageReader source, int minIndex);
+    
+    /**
+     * Notifies that a thumbnail read operation has been completed.
+     * 
+     * @param source the ImageReader object which calls this method.
+     */
+    void thumbnailComplete(ImageReader source);
+    
+    /**
+     * Notifies this listener about the degree of completion of the read call.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param percentageDone the percentage of decoding done.
+     */
+    void thumbnailProgress(ImageReader source, float percentageDone);
+    
+    /**
+     * Notifies this listener that a thumbnail reading operation has been started. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param imageIndex the index of the image in an input file or 
+     * stream to be read.
+     * @param thumbnailIndex the index of the thumbnail to be read.
+     */
+    void thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex);
+}
+
diff --git a/awt/javax/imageio/event/IIOReadUpdateListener.java b/awt/javax/imageio/event/IIOReadUpdateListener.java
new file mode 100644
index 0000000..ce5e2f1
--- /dev/null
+++ b/awt/javax/imageio/event/IIOReadUpdateListener.java
@@ -0,0 +1,138 @@
+/*
+ *  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.event;
+
+import java.awt.image.BufferedImage;
+import java.util.EventListener;
+import javax.imageio.ImageReader;
+
+/*
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * The IIOReadUpdateListener interface provides functionality 
+ * to receive notification of pixel updates during image and thumbnail 
+ * reading operations.
+ */
+public interface IIOReadUpdateListener extends EventListener {
+
+    /**
+     * Notifies this listener that the specified area of the image has been updated. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theImage the image to be updated.
+     * @param minX the minimum X coordinate of the pixels in the updated area.
+     * @param minY the minimum Y coordinate of the pixels in the updated area.
+     * @param width the width of updated area.
+     * @param height the height of updated area.
+     * @param periodX the horizontal spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels. 
+     * @param periodY the vertical spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels.
+     * @param bands the array of int values indicating the bands being updated.
+     */
+    void imageUpdate(ImageReader source, BufferedImage theImage, int minX,
+            int minY, int width, int height, int periodX, int periodY,
+            int[] bands);
+    
+    /**
+     * Notifies this listener that the current read operation has completed a 
+     * progressive pass.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theImage the image to be updated.
+     */
+    void passComplete(ImageReader source, BufferedImage theImage);
+    
+    /**
+     * Notifies this listener that the current read operation has begun 
+     * a progressive pass.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theImage the image to be updated.
+     * @param pass the numer of the pass.
+     * @param minPass the index of the first pass that will be decoded.
+     * @param maxPass the index of the last pass that will be decoded.
+     * @param minX the minimum X coordinate of the pixels in the updated area.
+     * @param minY the minimum Y coordinate of the pixels in the updated area.
+     * @param periodX the horizontal spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels. 
+      * @param periodY the vertical spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels.
+     * @param bands the array of int values indicating the bands being updated.
+     */
+    void passStarted(ImageReader source, BufferedImage theImage, int pass,
+            int minPass, int maxPass, int minX, int minY, int periodX,
+            int periodY, int[] bands);
+
+    /**
+     * Notifies this listener that the current thumbnail read operation has  
+     * completed a progressive pass.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theImage the thumbnail to be updated.
+     */
+    void thumbnailPassComplete(ImageReader source, BufferedImage theImage);
+    
+    /**
+     * Notifies this listener that the current thumbnail read operation has  
+     * begun a progressive pass.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theThumbnail the thumbnail to be updated.
+     * @param pass the numer of the pass.
+     * @param minPass the index of the first pass that will be decoded.
+     * @param maxPass the index of the last pass that will be decoded.
+     * @param minX the minimum X coordinate of the pixels in the updated area.
+     * @param minY the minimum Y coordinate of the pixels in the updated area.
+     * @param periodX the horizontal spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels. 
+     * @param periodY the vertical spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels.
+     * @param bands the array of int values indicating the bands being updated.
+     */
+    void thumbnailPassStarted(ImageReader source, BufferedImage theThumbnail,
+            int pass, int minPass, int maxPass, int minX, int minY,
+            int periodX, int periodY, int[] bands);
+    
+    /**
+     * Notifies this listener that a specified area of a thumbnail image has been 
+     * updated.
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param theThumbnail the thumbnail to be updated.
+     * @param minX the minimum X coordinate of the pixels in the updated area.
+     * @param minY the minimum Y coordinate of the pixels in the updated area.
+     * @param width the width of updated area.
+     * @param height the height of updated area.
+     * @param periodX the horizontal spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels. 
+     * @param periodY the vertical spacing period between updated 
+     * pixels, if it equals 1, there is no space between pixels.
+     * @param bands the array of int values indicating the bands being updated.
+     */
+    void thumbnailUpdate(ImageReader source, BufferedImage theThumbnail,
+            int minX, int minY, int width, int height, int periodX,
+            int periodY, int[] bands);
+}
+
diff --git a/awt/javax/imageio/event/IIOReadWarningListener.java b/awt/javax/imageio/event/IIOReadWarningListener.java
new file mode 100644
index 0000000..92fa275
--- /dev/null
+++ b/awt/javax/imageio/event/IIOReadWarningListener.java
@@ -0,0 +1,46 @@
+/*
+ *  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.event;
+
+import java.util.EventListener;
+import javax.imageio.ImageReader;
+
+/* 
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * The IIOReadWarningListener provides methods to receive notification
+ * of warning messages generated by image 
+ * and thumbnail reading methods.
+ */
+public interface IIOReadWarningListener extends EventListener {
+
+    /**
+     * Notifies this listener about a warning (non-fatal error) during decoding. 
+     * 
+     * @param source the ImageReader object which calls this method.
+     * @param warning the string describing the warning.
+     */
+    public void warningOccurred(ImageReader source, String warning);
+}
+
diff --git a/awt/javax/imageio/event/IIOWriteProgressListener.java b/awt/javax/imageio/event/IIOWriteProgressListener.java
new file mode 100644
index 0000000..19ae495
--- /dev/null
+++ b/awt/javax/imageio/event/IIOWriteProgressListener.java
@@ -0,0 +1,86 @@
+/*
+ *  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.event;
+
+import javax.imageio.ImageWriter;
+import java.util.EventListener;
+
+/**
+ * The IIOWriteProgressListener interface provides methods to 
+ * receive notification about the progress of the image and 
+ * thumbnail writing methods.
+ */
+public interface IIOWriteProgressListener extends EventListener {
+    
+    /**
+     * Notifies this listener that an image write operation has been started. 
+     * 
+     * @param source the ImageWriter object which calls this method.
+     * @param imageIndex the index of the image being written.
+     */
+    void imageStarted(ImageWriter source, int imageIndex);
+    
+    /**
+     * Notifies this listener about the degree of completion of the write call.
+     * 
+     * @param source the ImageWriter object which calls this method.
+     * @param percentageDone the percentage of encoding done.
+     */
+    void imageProgress(ImageWriter source, float percentageDone);
+    
+    /**
+     * Notifies this listener that the image writing has been completed. 
+     * 
+     * @param source the ImageWriter object which calls this method.
+     */
+    void imageComplete(ImageWriter source);
+    
+    /**
+     * Notifies this listener that a thumbnail write operation has been started. 
+     * 
+     * @param source the ImageWriter object which calls this method.
+     * @param imageIndex the index of the image being written.
+     * @param thumbnailIndex the index of the thumbnail being written.
+     */
+    void thumbnailStarted(ImageWriter source, int imageIndex, int thumbnailIndex);
+    
+    /**
+     * Notifies this listener about the degree of completion of the write call.
+     * 
+     * @param source the ImageWriter object which calls this method.
+     * @param percentageDone the percentage of encoding done.
+     */
+    void thumbnailProgress(ImageWriter source, float percentageDone);
+    
+    /**
+     * Notifies this listener that a thumbnail write operation has been completed.
+     * 
+     * @param source the ImageWriter object which calls this method.
+     */
+    void thumbnailComplete(ImageWriter source);
+    
+    /**
+     * Notifies this listener that writing operation has been aborted.
+     * 
+     * @param source the ImageWriter object which calls this method.
+     */
+    void writeAborted(ImageWriter source);
+}
diff --git a/awt/javax/imageio/event/IIOWriteWarningListener.java b/awt/javax/imageio/event/IIOWriteWarningListener.java
new file mode 100644
index 0000000..f530d25
--- /dev/null
+++ b/awt/javax/imageio/event/IIOWriteWarningListener.java
@@ -0,0 +1,40 @@
+/*
+ *  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.event;
+
+import javax.imageio.ImageWriter;
+import java.util.EventListener;
+
+/**
+ * The IIOWriteWarningListener provides methods to receive notification
+ * of warnings generated by image and thumbnail writing methods.
+ */
+public interface IIOWriteWarningListener extends EventListener {
+    
+    /**
+     * Notifies this listener about a warning (non-fatal error) during encoding. 
+     * 
+     * @param source the ImageWriter object which calls this method.
+     * @param imageIndex the index of the image generating the warning.
+     * @param warning the string describing the warning.
+     */
+    void warningOccurred(ImageWriter source, int imageIndex, String warning);
+}
diff --git a/awt/javax/imageio/metadata/IIOInvalidTreeException.java b/awt/javax/imageio/metadata/IIOInvalidTreeException.java
new file mode 100644
index 0000000..8690b2b
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOInvalidTreeException.java
@@ -0,0 +1,67 @@
+/*
+ *  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.metadata;
+
+import org.w3c.dom.Node;
+import javax.imageio.IIOException;
+
+/**
+ * The IIOInvalidTreeException provides notification about
+ * fails of IIOMetadataNodes tree parsing by IIOMetadata object. 
+ */
+public class IIOInvalidTreeException extends IIOException {
+    
+    /** The offending node. */
+    protected Node offendingNode = null;
+
+    /**
+     * Instantiates an IIOInvalidTreeException with the
+     * specified detailed message and specified offending
+     * Node.
+     * 
+     * @param message the detailed message.
+     * @param offendingNode the offending node.
+     */
+    public IIOInvalidTreeException(String message, Node offendingNode) {
+        super(message);
+        this.offendingNode = offendingNode;
+    }
+
+    /**
+     * Instantiates a new IIOInvalidTreeException with the
+     * specified detailed message and specified offending
+     * Node.
+     * 
+     * @param message the detailed message.
+     * @param cause the cause of this exception.
+     * @param offendingNode the offending node
+     */
+    public IIOInvalidTreeException(String message, Throwable cause, Node offendingNode) {
+        super(message, cause);
+        this.offendingNode = offendingNode;
+    }
+
+    /**
+     * Gets the offending node.
+     * 
+     * @return the offending node.
+     */
+    public Node getOffendingNode() {
+        return offendingNode;
+    }
+}
diff --git a/awt/javax/imageio/metadata/IIOMetadata.java b/awt/javax/imageio/metadata/IIOMetadata.java
new file mode 100644
index 0000000..f2387cc
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOMetadata.java
@@ -0,0 +1,371 @@
+/*
+ *  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.metadata;
+
+import java.util.ArrayList;
+
+import org.apache.harmony.x.imageio.metadata.IIOMetadataUtils;
+import org.w3c.dom.Node;
+
+/**
+ * The Class IIOMetadata represents the metadata (bundled with an image)
+ * as a Dom-type tree.
+ */
+public abstract class IIOMetadata {
+
+    /** Whether the standard metadata format is supported. */
+    protected boolean standardFormatSupported;
+    
+    /** The native metadata format name. */
+    protected String nativeMetadataFormatName;
+    
+    /** The native metadata format class name. */
+    protected String nativeMetadataFormatClassName;
+    
+    /** The extra metadata format names. */
+    protected String[] extraMetadataFormatNames;
+    
+    /** The extra metadata format class names. */
+    protected String[] extraMetadataFormatClassNames;
+    
+    /** The default controller. */
+    protected IIOMetadataController defaultController;
+    
+    /** The controller. */
+    protected IIOMetadataController controller;
+
+    /**
+     * Instantiates a new IIOMetadata with no data set.
+     */
+    protected IIOMetadata() {}
+
+    /**
+     * Instantiates a new IIOMetadata with the specified data parameters.
+     * 
+     * @param standardMetadataFormatSupported whether the standard metadata format is supported
+     * @param nativeMetadataFormatName the native metadata format name
+     * @param nativeMetadataFormatClassName the native metadata format class name
+     * @param extraMetadataFormatNames the extra metadata format names
+     * @param extraMetadataFormatClassNames the extra metadata format class names
+     */
+    protected IIOMetadata(boolean standardMetadataFormatSupported,
+                          String nativeMetadataFormatName,
+                          String nativeMetadataFormatClassName,
+                          String[] extraMetadataFormatNames,
+                          String[] extraMetadataFormatClassNames) {
+        standardFormatSupported = standardMetadataFormatSupported;
+        this.nativeMetadataFormatName = nativeMetadataFormatName;
+        this.nativeMetadataFormatClassName = nativeMetadataFormatClassName;
+        if (extraMetadataFormatNames == null) {
+            if (extraMetadataFormatClassNames != null) {
+                throw new IllegalArgumentException(
+                        "extraMetadataFormatNames == null && extraMetadataFormatClassNames != null!"
+                );
+            }
+        } else {
+            if (extraMetadataFormatClassNames == null) {
+                throw new IllegalArgumentException(
+                        "extraMetadataFormatNames != null && extraMetadataFormatClassNames == null!"
+                );
+            }
+            if (extraMetadataFormatNames.length == 0) {
+                throw new IllegalArgumentException("extraMetadataFormatNames.length == 0!");
+            }
+            if (extraMetadataFormatClassNames.length != extraMetadataFormatNames.length) {
+                throw new IllegalArgumentException(
+                        "extraMetadataFormatClassNames.length != extraMetadataFormatNames.length!"
+                );
+            }
+            this.extraMetadataFormatNames = extraMetadataFormatNames.clone();
+            this.extraMetadataFormatClassNames = extraMetadataFormatClassNames.clone();
+        }
+    }
+
+    /**
+     * Gets the metadata as tree-type document.
+     * 
+     * @param formatName the format name
+     * 
+     * @return the node in tree format
+     */
+    public abstract Node getAsTree(String formatName);
+    
+    /**
+     * Checks if the metadata is read only.
+     * 
+     * @return true, if the metadata is read only.
+     */
+    public abstract boolean isReadOnly();
+    
+    /**
+     * Merges the specified tree with this metadata tree.
+     * 
+     * @param formatName the format of the specified tree
+     * @param root the root node of the metadata tree
+     * 
+     * @throws IIOInvalidTreeException if the specified tree
+     * is incompatible with the this metadata tree.
+     */
+    public abstract void mergeTree(String formatName, Node root) throws IIOInvalidTreeException;
+    
+    /**
+     * Resets the controller.
+     */
+    public abstract void reset();
+
+    /**
+     * Gets the controller associated with this metadata document.
+     * 
+     * @return the controller
+     */
+    public IIOMetadataController getController() {
+        return controller;
+    }
+
+    /**
+     * Checks whether this metadata has a controller.
+     * 
+     * @return true, if this metadata has a controller
+     */
+    public boolean hasController() {
+        return getController() != null;
+    }
+
+    /**
+     * Activate the controller.
+     * 
+     * @return true, if successful
+     */
+    public boolean activateController() {
+        if (!hasController()) {
+            throw new IllegalStateException("hasController() == false!");
+        }
+        return getController().activate(this);
+    }
+
+    /**
+     * Gets the default controller.
+     * 
+     * @return the default controller
+     */
+    public IIOMetadataController getDefaultController() {
+        return defaultController;
+    }
+
+    /**
+     * Gets the extra metadata format names.
+     * 
+     * @return the extra metadata format names
+     */
+    public String[] getExtraMetadataFormatNames() {
+        return extraMetadataFormatNames == null ? null : extraMetadataFormatNames.clone();
+    }
+
+    /**
+     * Gets the metadata format.
+     * 
+     * @param formatName the format name
+     * 
+     * @return the metadata format
+     */
+    public IIOMetadataFormat getMetadataFormat(String formatName) {
+        return IIOMetadataUtils.instantiateMetadataFormat(
+                formatName,
+                standardFormatSupported,
+                nativeMetadataFormatName, nativeMetadataFormatClassName,
+                extraMetadataFormatNames, extraMetadataFormatClassNames
+        );
+    }
+
+    /**
+     * Gets the native metadata format name.
+     * 
+     * @return the native metadata format name
+     */
+    public String getNativeMetadataFormatName() {
+        return nativeMetadataFormatName;
+    }
+
+    /**
+     * Checks if the standard metadata format is supported.
+     * 
+     * @return true, if the standard metadata format is supported
+     */
+    public boolean isStandardMetadataFormatSupported() {
+        return standardFormatSupported;
+    }
+
+    /**
+     * Gets the metadata format names.
+     * 
+     * @return the metadata format names
+     */
+    public String[] getMetadataFormatNames() {
+        ArrayList<String> res = new ArrayList<String>();
+
+        String nativeMetadataFormatName = getNativeMetadataFormatName();
+        boolean standardFormatSupported = isStandardMetadataFormatSupported();
+        String extraMetadataFormatNames[] = getExtraMetadataFormatNames();
+
+        if (standardFormatSupported) {
+            res.add(IIOMetadataFormatImpl.standardMetadataFormatName);
+        }
+        if (nativeMetadataFormatName != null) {
+            res.add(nativeMetadataFormatName);
+        }
+        if (extraMetadataFormatNames != null) {
+            for (String extraMetadataFormatName : extraMetadataFormatNames) {
+                res.add(extraMetadataFormatName);
+            }
+        }
+
+        return res.size() > 0 ? res.toArray(new String[0]) : null;
+    }
+
+    /**
+     * Gets the standard chroma node.
+     * 
+     * @return the standard chroma node
+     */
+    protected IIOMetadataNode getStandardChromaNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard compression node.
+     * 
+     * @return the standard compression node
+     */
+    protected IIOMetadataNode getStandardCompressionNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard data node.
+     * 
+     * @return the standard data node
+     */
+    protected IIOMetadataNode getStandardDataNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard dimension node.
+     * 
+     * @return the standard dimension node
+     */
+    protected IIOMetadataNode getStandardDimensionNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard document node.
+     * 
+     * @return the standard document node
+     */
+    protected IIOMetadataNode getStandardDocumentNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard text node.
+     * 
+     * @return the standard text node
+     */
+    protected IIOMetadataNode getStandardTextNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard tile node.
+     * 
+     * @return the standard tile node
+     */
+    protected IIOMetadataNode getStandardTileNode() {
+        return null;
+    }
+
+    /**
+     * Gets the standard transparency node.
+     * 
+     * @return the standard transparency node
+     */
+    protected IIOMetadataNode getStandardTransparencyNode() {
+        return null;
+    }
+
+    /**
+     * Gets the metadata as a tree in standard format.
+     * 
+     * @return the metadata as a tree in standard format
+     */
+    protected final IIOMetadataNode getStandardTree() {
+        // Create root node
+        IIOMetadataNode root = new IIOMetadataNode(IIOMetadataFormatImpl.standardMetadataFormatName);
+
+        Node node;
+        if ((node = getStandardChromaNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardCompressionNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardDataNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardDimensionNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardDocumentNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardTextNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardTileNode()) != null) {
+            root.appendChild(node);
+        }
+        if ((node = getStandardTransparencyNode()) != null) {
+            root.appendChild(node);
+        }
+        
+        return root;
+    }
+
+    /**
+     * Sets the controller.
+     * 
+     * @param controller the new controller
+     */
+    public void setController(IIOMetadataController controller) {
+        this.controller = controller;
+    }
+
+    /**
+     * Sets the from tree.
+     * 
+     * @param formatName the name of the metatdata format of the from tree
+     * @param root the root node of the from tree
+     * 
+     * @throws IIOInvalidTreeException if the tree or its format is not compatible with 
+     * this metadata.
+     */
+    public void setFromTree(String formatName, Node root) throws IIOInvalidTreeException {
+        reset();
+        mergeTree(formatName, root);
+    }
+}
diff --git a/awt/javax/imageio/metadata/IIOMetadataController.java b/awt/javax/imageio/metadata/IIOMetadataController.java
new file mode 100644
index 0000000..dfd4e5c
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOMetadataController.java
@@ -0,0 +1,45 @@
+/*
+ *  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.metadata;
+
+/* 
+ * @author Sergey I. Salishev
+ * @version $Revision: 1.2 $
+ */
+
+/**
+ * The IIOMetadataController interface provides a method for 
+ * implementing objects to activate the controller without 
+ * defining how the controller obtains values.
+ */
+public interface IIOMetadataController {
+
+    /**
+     * Activates a controller.
+     * 
+     * @param metadata the metadata to be modified.
+     * 
+     * @return true if the IIOMetadata has been modified, 
+     * false otherwise.
+     */
+    public boolean activate(IIOMetadata metadata);
+}
+
diff --git a/awt/javax/imageio/metadata/IIOMetadataFormat.java b/awt/javax/imageio/metadata/IIOMetadataFormat.java
new file mode 100644
index 0000000..9e246b4
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOMetadataFormat.java
@@ -0,0 +1,347 @@
+/*
+ *  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.metadata;
+
+import javax.imageio.ImageTypeSpecifier;
+import java.util.Locale;
+
+/**
+ * The Interface IIOMetadataFormat is implemented by classes that 
+ * describe the rules and allowed elements for a metadata document
+ * tree.
+ */
+public interface IIOMetadataFormat {
+
+    /** The CHILD_POLICY_EMPTY. */
+    int CHILD_POLICY_EMPTY = 0;
+    
+    /** The CHILD_POLICY_ALL. */
+    int CHILD_POLICY_ALL = 1;
+    
+    /** The CHILD_POLICY_SOME. */
+    int CHILD_POLICY_SOME = 2;
+    
+    /** The CHILD_POLICY_CHOICE. */
+    int CHILD_POLICY_CHOICE = 3;
+    
+    /** The CHILD_POLICY_SEQUENCE. */
+    int CHILD_POLICY_SEQUENCE = 4;
+    
+    /** The CHILD_POLICY_REPEAT. */
+    int CHILD_POLICY_REPEAT = 5;
+    
+    /** The maximum value for the child policy. */
+    int CHILD_POLICY_MAX = CHILD_POLICY_REPEAT;
+
+    /** The DATATYPE_STRING. */
+    int DATATYPE_STRING = 0;
+    
+    /** The DATATYPE_BOOLEAN. */
+    int DATATYPE_BOOLEAN = 1;
+    
+    /** The DATATYPE_INTEGER. */
+    int DATATYPE_INTEGER = 2;
+    
+    /** The DATATYPE_FLOAT. */
+    int DATATYPE_FLOAT = 3;
+    
+    /** The DATATYPE_DOUBLE. */
+    int DATATYPE_DOUBLE = 4;
+
+    /** The VALUE_NONE. */
+    int VALUE_NONE = 0;
+    
+    /** The VALUE_ARBITRARY. */
+    int VALUE_ARBITRARY = 1;
+    
+    /** The VALUE_RANGE. */
+    int VALUE_RANGE = 2;
+    
+    /** The VALUE_RANGE_MIN_INCLUSIVE_MASK. */
+    int VALUE_RANGE_MIN_INCLUSIVE_MASK = 4;
+    
+    /** The VALUE_RANGE_MAX_INCLUSIVE_MASK. */
+    int VALUE_RANGE_MAX_INCLUSIVE_MASK = 8;
+    
+    /** The VALUE_ENUMERATION. */
+    int VALUE_ENUMERATION = 16;
+    
+    /** The VALUE_LIST. */
+    int VALUE_LIST = 32;
+    
+    /** The VALUE_RANGE_MIN_INCLUSIVE. */
+    int VALUE_RANGE_MIN_INCLUSIVE = VALUE_RANGE | VALUE_RANGE_MIN_INCLUSIVE_MASK;
+    
+    /** The VALUE_RANGE_MAX_INCLUSIVE. */
+    int VALUE_RANGE_MAX_INCLUSIVE = VALUE_RANGE | VALUE_RANGE_MAX_INCLUSIVE_MASK;
+    
+    /** The VALUE_RANGE_MIN_MAX_INCLUSIVE. */
+    int VALUE_RANGE_MIN_MAX_INCLUSIVE =
+            VALUE_RANGE | VALUE_RANGE_MIN_INCLUSIVE_MASK | VALUE_RANGE_MAX_INCLUSIVE_MASK;
+
+    /**
+     * Tells whether the specified element is allowed for the specified 
+     * image type.
+     * 
+     * @param elementName the element name
+     * @param imageType the image type
+     * 
+     * @return true, if the specified element is allowed for the specified 
+     * image type
+     */
+    boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType);
+
+    /**
+     * Gets data type of the specified attribute of the specified element.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the attribute's data type
+     */
+    int getAttributeDataType(String elementName, String attrName);
+    
+    /**
+     * Gets the default value of the specified attribute of the specified element.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the attribute's default value
+     */
+    String getAttributeDefaultValue(String elementName, String attrName);
+    
+    /**
+     * Gets the user-friendly description of the attribute.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * @param locale the locale giving the desired language for the
+     * description
+     * 
+     * @return the attribute description
+     */
+    String getAttributeDescription(String elementName, String attrName, Locale locale);
+    
+    /**
+     * Gets the attribute enumerations.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the attribute enumerations
+     */
+    String[] getAttributeEnumerations(String elementName, String attrName);
+    
+    /**
+     * Gets the maximum length of the attribute list.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the maximum length of the attribute list
+     */
+    int getAttributeListMaxLength(String elementName, String attrName);
+    
+    /**
+     * Gets the minimum length of the attribute list.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the minimum length of the attribute list
+     */
+    int getAttributeListMinLength(String elementName, String attrName);
+    
+    /**
+     * Gets the maximum value allowed for the attribute.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the maximum value allowed for the attribute
+     */
+    String getAttributeMaxValue(String elementName, String attrName);
+    
+    /**
+     * Gets the minimum value allowed for the attribute.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the minimum value allowed for the attribute
+     */
+    String getAttributeMinValue(String elementName, String attrName);
+    
+    /**
+     * Gets the attribute names allowed for the specified element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the attribute names
+     */
+    String[] getAttributeNames(String elementName);
+    
+    /**
+     * Gets the attribute value type.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return the attribute value type
+     */
+    int getAttributeValueType(String elementName, String attrName);
+    
+    /**
+     * Checks whether the specified attribute is required 
+     * for the specified element.
+     * 
+     * @param elementName the element name
+     * @param attrName the attribute name
+     * 
+     * @return true, if the specified attribute is required for the 
+     * specified element
+     */
+    boolean isAttributeRequired(String elementName, String attrName);
+
+    /**
+     * Gets the names of the possible child elements for the given element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the child names
+     */
+    String[] getChildNames(String elementName);
+    
+    /**
+     * Gets the constant describing the element's child policy.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the child policy
+     */
+    int getChildPolicy(String elementName);
+
+    /**
+     * Gets the user-friendly description of the element.
+     * 
+     * @param elementName the element name
+     * @param locale the locale giving the desired language for the
+     * description
+     * 
+     * @return the element description
+     */
+    String getElementDescription(String elementName, Locale locale);
+    
+    /**
+     * Gets the maximum number of children allowed for the element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the maximum number of children allowed for the element
+     */
+    int getElementMaxChildren(String elementName);
+    
+    /**
+     * Gets the minimum number of children allowed for the element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the minimum number of children allowed for the element
+     */
+    int getElementMinChildren(String elementName);
+
+    /**
+     * Gets the maximum object array length allowed for the element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the maximum object array length allowed for the element
+     */
+    int getObjectArrayMaxLength(String elementName);
+    
+    /**
+     * Gets the minimum object array length allowed for the element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the minimum object array length allowed for the element
+     */
+    int getObjectArrayMinLength(String elementName);
+    
+    /**
+     * Gets the object class corresponding to the specified element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the object class corresponding to the specified element
+     */
+    Class<?> getObjectClass(String elementName);
+    
+    /**
+     * Gets the object default value for the element.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the object default value for the element
+     */
+    Object getObjectDefaultValue(String elementName);
+    
+    /**
+     * Gets the object enumerations.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the object enumerations
+     */
+    Object[] getObjectEnumerations(String elementName);
+    
+    /**
+     * Gets the maximum value allowed for the element's object.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the maximum value allowed for the element's object
+     */
+    Comparable<?> getObjectMaxValue(String elementName);
+    
+    /**
+     * Gets the minimum value allowed for the element's object.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the minimum value allowed for the element's object
+     */
+    Comparable<?> getObjectMinValue(String elementName);
+    
+    /**
+     * Gets the constant that indicates the type of the element's value.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the constant that indicates the type of the element's value
+     */
+    int getObjectValueType(String elementName);
+
+    /**
+     * Gets the name of the root element.
+     * 
+     * @return the name of the root element
+     */
+    String getRootName();
+}
diff --git a/awt/javax/imageio/metadata/IIOMetadataFormatImpl.java b/awt/javax/imageio/metadata/IIOMetadataFormatImpl.java
new file mode 100644
index 0000000..438ae90
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOMetadataFormatImpl.java
@@ -0,0 +1,939 @@
+/*
+ *  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.metadata;
+
+import javax.imageio.ImageTypeSpecifier;
+import java.util.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * The IIOMetadataFormatImpl class provides an implementation of the 
+ * IIOMetadataFormat interface.
+ */
+public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat {
+    
+    /** The Constant standardMetadataFormatName. */
+    @SuppressWarnings({"ConstantDeclaredInAbstractClass"})
+    public static final String standardMetadataFormatName = "javax_imageio_1.0";
+
+    /** The standard format. */
+    @SuppressWarnings({"StaticNonFinalField"})
+    private static IIOMetadataFormatImpl standardFormat;
+
+    /** The root name. */
+    private String rootName;
+    
+    /** The element hash. */
+    private HashMap<String, Element> elementHash = new HashMap<String, Element>();
+
+    /** The resource base name. */
+    private String resourceBaseName = getClass().getName() + "Resources";
+
+    /**
+     * Instantiates an IIOMetadataFormatImpl with the specified root
+     * name and child policy (not CHILD_POLICY_REPEAT).
+     * 
+     * @param rootName the name of root element.
+     * @param childPolicy the child policy defined by one of the 
+     * CHILD_POLICY_* constants  (except CHILD_POLICY_REPEAT).
+     */
+    public IIOMetadataFormatImpl(String rootName, int childPolicy) {
+        if (rootName == null) {
+            throw new IllegalArgumentException("rootName is null");
+        }
+        if (
+                childPolicy < CHILD_POLICY_EMPTY ||
+                childPolicy > CHILD_POLICY_MAX ||
+                childPolicy == CHILD_POLICY_REPEAT
+        ) {
+            throw new IllegalArgumentException("childPolicy is not one of the predefined constants");
+        }
+
+        this.rootName = rootName;
+        Element root = new Element();
+        root.name = rootName;
+        root.childPolicy = childPolicy;
+        elementHash.put(rootName, root);
+    }
+
+    /**
+     * Instantiates an IIOMetadataFormatImpl with the specified root
+     * name and CHILD_POLICY_REPEAT child policy.
+     * 
+     * @param rootName the name of root element.
+     * @param minChildren the minimum number of children.
+     * @param maxChildren the maximum number of children
+     */
+    public IIOMetadataFormatImpl(String rootName, int minChildren, int maxChildren) {
+        if (rootName == null) {
+            throw new IllegalArgumentException("rootName is null");
+        }
+        if (minChildren < 0) {
+            throw new IllegalArgumentException("minChildren < 0!");
+        }
+        if (minChildren > maxChildren) {
+            throw new IllegalArgumentException("minChildren > maxChildren!");
+        }
+
+        this.rootName = rootName;
+        Element root = new Element();
+        root.name = rootName;
+        root.minChildren = minChildren;
+        root.maxChildren = maxChildren;
+        root.childPolicy = CHILD_POLICY_REPEAT;
+        elementHash.put(rootName, root);
+    }
+
+    @SuppressWarnings({"AbstractMethodOverridesAbstractMethod"})
+    public abstract boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType);
+
+    /**
+     * Adds a new attribute to an existing element.
+     * 
+     * @param elementName the name of the element to which the new attribute
+     * will be added.
+     * @param attrName the attribute name.
+     * @param dataType the data type of the new attribute.
+     * @param required the flag which indicates whether this attribute
+     * must be present.
+     * @param listMinLength the minimum legal number of list items.
+     * @param listMaxLength the the maximum legal number of list items.
+     */
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, int listMinLength, int listMaxLength
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+        if (listMinLength < 0 || listMinLength > listMaxLength) {
+            throw new IllegalArgumentException("Invalid list bounds!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.listMinLength = listMinLength;
+        attr.listMaxLength = listMaxLength;
+        attr.valueType = VALUE_LIST;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    /**
+     * Adds a new attribute to an existing element.
+     * 
+     * @param elementName the name of the element to which the new attribute
+     * will be added.
+     * @param attrName the attribute name.
+     * @param dataType the data type of the new attribute.
+     * @param required the flag which indicates whether this attribute
+     * must be present.
+     * @param defaultValue the default value of the attribute.
+     */
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, String defaultValue
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.defaultValue = defaultValue;
+        attr.valueType = VALUE_ARBITRARY;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    /**
+     * Adds a new attribute to an existing element.
+     * 
+     * @param elementName the name of the element to which the new attribute
+     * will be added.
+     * @param attrName the attribute name.
+     * @param dataType the data type of the new attribute.
+     * @param required the flag which indicates whether this attribute
+     * must be present.
+     * @param defaultValue the default value of the attribute.
+     * @param enumeratedValues the legal values for the attribute as 
+     * a list of strings.
+     */
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, String defaultValue, List<String> enumeratedValues
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+        if (enumeratedValues == null || enumeratedValues.isEmpty()) {
+            throw new IllegalArgumentException("enumeratedValues is empty or null");
+        }
+
+        try {
+            for (String enumeratedValue : enumeratedValues) {
+                if (enumeratedValue == null) {
+                    throw new IllegalArgumentException("enumeratedValues contains a null!");
+                }
+            }
+        } catch (ClassCastException e) {
+            throw new IllegalArgumentException("enumeratedValues contains a non-String value!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.defaultValue = defaultValue;
+        attr.enumeratedValues = enumeratedValues;
+        attr.valueType = VALUE_ENUMERATION;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    /**
+     * Adds a new attribute to an existing element.
+     * 
+     * @param elementName the name of the element to which the new attribute
+     * will be added.
+     * @param attrName the attribute name.
+     * @param dataType the data type of the new attribute.
+     * @param required the flag which indicates whether this attribute
+     * must be present.
+     * @param defaultValue the default value of attribute.
+     * @param minValue the minimum legal value of an attribute.
+     * @param maxValue the maximum legal value of an attribute.
+     * @param minInclusive the flag which indicates  
+     * whether the minValue is inclusive.
+     * @param maxInclusive the flag which indicates  
+     * whether the maxValue is inclusive.
+     */
+    protected void addAttribute(
+            String elementName, String attrName, int dataType,
+            boolean required, String defaultValue,
+            String minValue, String maxValue,
+            boolean minInclusive, boolean maxInclusive
+    ) {
+        if (attrName == null) {
+            throw new IllegalArgumentException("attrName == null!");
+        }
+        if (dataType < DATATYPE_STRING || dataType > DATATYPE_DOUBLE) {
+            throw new IllegalArgumentException("Invalid value for dataType!");
+        }
+
+        Element element = findElement(elementName);
+        Attlist attr = new Attlist();
+        attr.name = attrName;
+        attr.dataType = dataType;
+        attr.required = required;
+        attr.defaultValue = defaultValue;
+        attr.minValue = minValue;
+        attr.maxValue = maxValue;
+        attr.minInclusive = minInclusive;
+        attr.maxInclusive = maxInclusive;
+
+        attr.valueType = VALUE_RANGE;
+        attr.valueType |= minInclusive ? VALUE_RANGE_MIN_INCLUSIVE_MASK : 0;
+        attr.valueType |= maxInclusive ? VALUE_RANGE_MAX_INCLUSIVE_MASK : 0;
+
+        element.attributes.put(attrName, attr);
+    }
+
+    /**
+     * Adds a new attribute with boolean data type to an existing 
+     * element.
+     * 
+     * @param elementName the name of the element to which the new attribute
+     * will be added.
+     * @param attrName the attribute name.
+     * @param hasDefaultValue the flag which indicates whether this attribute
+     * must have a default value.
+     * @param defaultValue the default value.
+     */
+    protected void addBooleanAttribute(
+            String elementName, String attrName,
+            boolean hasDefaultValue, boolean defaultValue
+    ) {
+        String defaultVal = hasDefaultValue ? (defaultValue ? "TRUE" : "FALSE") : null;
+        ArrayList<String> values = new ArrayList<String>(2);
+        values.add("TRUE");
+        values.add("FALSE");
+
+        addAttribute(elementName, attrName, DATATYPE_BOOLEAN, true, defaultVal, values);
+    }
+
+    /**
+     * Adds an existing element to the list of child elements 
+     * of the specified parent element.
+     * 
+     * @param elementName the name of the element to be added.
+     * @param parentName the parent element name.
+     */
+    protected void addChildElement(String elementName, String parentName) {
+        Element parent = findElement(parentName);
+        Element element = findElement(elementName);
+        parent.children.add(element.name);
+    }
+
+    /**
+     * Adds a new element type to this IIOMetadataFormat with 
+     * a child policy (if policy is not CHILD_POLICY_REPEAT).
+     * 
+     * @param elementName the name of the element to be added.
+     * @param parentName the parent element name.
+     * @param childPolicy one of the CHILD_POLICY_* constants defined
+     * by IIOMetadataFormat.
+     */
+    protected void addElement(String elementName, String parentName, int childPolicy) {
+        if (
+                childPolicy < CHILD_POLICY_EMPTY ||
+                childPolicy > CHILD_POLICY_MAX ||
+                childPolicy == CHILD_POLICY_REPEAT
+        ) {
+            throw new IllegalArgumentException("childPolicy is not one of the predefined constants");
+        }
+        
+        Element parent = findElement(parentName);
+        Element element = new Element();
+        element.name = elementName;
+        element.childPolicy = childPolicy;
+        elementHash.put(elementName, element);
+        parent.children.add(elementName);
+    }
+
+    /**
+     * Adds a new element type to this IIOMetadataFormat with 
+     * CHILD_POLICY_REPEAT and the specified minimum and maximum
+     * number of child elements.
+     * 
+     * @param elementName the element name to be added.
+     * @param parentName the parent element name.
+     * @param minChildren the minimum number of child elements.
+     * @param maxChildren the maximum number of child elements.
+     */
+    protected void addElement(
+            String elementName, String parentName,
+            int minChildren, int maxChildren
+    ) {
+        if (minChildren < 0) {
+            throw new IllegalArgumentException("minChildren < 0!");
+        }
+        if (minChildren > maxChildren) {
+            throw new IllegalArgumentException("minChildren > maxChildren!");
+        }
+
+        Element parent = findElement(parentName);
+        Element element = new Element();
+        element.name = elementName;
+        element.childPolicy = CHILD_POLICY_REPEAT;
+        element.minChildren = minChildren;
+        element.maxChildren = maxChildren;
+        elementHash.put(elementName, element);
+        parent.children.add(elementName);
+    }
+
+    /**
+     * Adds an Object reference with the specified class type to be 
+     * stored as element's value. 
+     * 
+     * @param elementName the element name.
+     * @param classType the class indicates the legal types for 
+     * the object's value.
+     * @param arrayMinLength the minimum legal length for the array.
+     * @param arrayMaxLength the maximum legal length for the array.
+     */
+    protected void addObjectValue(
+            String elementName, Class<?> classType,
+            int arrayMinLength, int arrayMaxLength
+    ) {
+        Element element = findElement(elementName);
+
+        ObjectValue objVal = new ObjectValue();
+        objVal.classType = classType;
+        objVal.arrayMaxLength = arrayMaxLength;
+        objVal.arrayMinLength = arrayMinLength;
+        objVal.valueType = VALUE_LIST;
+
+        element.objectValue = objVal;
+    }
+
+    /**
+     * Adds an Object reference with the specified class type to be 
+     * stored as an element's value. 
+     * 
+     * @param elementName the element name.
+     * @param classType the class indicates the legal types for 
+     * the object's value.
+     * @param required a flag indicated that this object value 
+     * must be present.
+     * @param defaultValue the default value, or null.
+     */
+    protected <T> void addObjectValue(
+            String elementName, Class<T> classType,
+            boolean required, T defaultValue
+    ) {
+        // note: reqired is an unused parameter
+        Element element = findElement(elementName);
+
+        ObjectValue<T> objVal = new ObjectValue<T>();
+        objVal.classType = classType;
+        objVal.defaultValue = defaultValue;
+        objVal.valueType = VALUE_ARBITRARY;
+
+        element.objectValue = objVal;
+    }
+
+    /**
+     * Adds an Object reference with the specified class type to be 
+     * stored as the element's value. 
+     * 
+     * @param elementName the element name.
+     * @param classType the class indicates the legal types for 
+     * the object value.
+     * @param required a flag indicated that this object value 
+     * must be present.
+     * @param defaultValue the default value, or null.
+     * @param enumeratedValues the list of legal values for the object.
+     */
+    protected <T> void addObjectValue(
+            String elementName, Class<T> classType,
+            boolean required, T defaultValue,
+            List<? extends T> enumeratedValues
+    ) {
+        // note: reqired is an unused parameter
+        if (enumeratedValues == null || enumeratedValues.isEmpty()) {
+            throw new IllegalArgumentException("enumeratedValues is empty or null");
+        }
+
+        try {
+            for (T enumeratedValue : enumeratedValues) {
+                if (enumeratedValue == null) {
+                    throw new IllegalArgumentException("enumeratedValues contains a null!");
+                }
+            }
+        } catch (ClassCastException e) {
+            throw new IllegalArgumentException("enumeratedValues contains a value not of class classType!");
+        }
+
+        Element element = findElement(elementName);
+
+        ObjectValue<T> objVal = new ObjectValue<T>();
+        objVal.classType = classType;
+        objVal.defaultValue = defaultValue;
+        objVal.enumeratedValues = enumeratedValues;
+        objVal.valueType = VALUE_ENUMERATION;
+
+        element.objectValue = objVal;
+    }
+
+    /**
+     * Adds an Object reference with the specified class type to be 
+     * stored as the element's value. 
+     * 
+     * @param elementName the element name.
+     * @param classType the class indicates the legal types for 
+     * the object value.
+     * @param defaultValue the default value, or null.
+     * @param minValue the minimum legal value for the object value. 
+     * @param maxValue the maximum legal value for the object value. 
+     * @param minInclusive the flag which indicates 
+     * whether the minValue is inclusive.
+     * @param maxInclusive the flag which indicates 
+     * whether the maxValue is inclusive.
+     */
+    protected <T extends Object & Comparable<? super T>> void addObjectValue(
+            String elementName, Class<T> classType,
+            T defaultValue, Comparable<? super T> minValue, Comparable<? super T> maxValue,
+            boolean minInclusive, boolean maxInclusive
+    ) {
+        Element element = findElement(elementName);
+
+        ObjectValue<T> objVal = new ObjectValue<T>();
+        objVal.classType = classType;
+        objVal.defaultValue = defaultValue;
+        objVal.minValue = minValue;
+        objVal.maxValue = maxValue;
+        objVal.minInclusive = minInclusive;
+        objVal.maxInclusive = maxInclusive;
+
+        objVal.valueType = VALUE_RANGE;
+        objVal.valueType |= minInclusive ? VALUE_RANGE_MIN_INCLUSIVE_MASK : 0;
+        objVal.valueType |= maxInclusive ? VALUE_RANGE_MAX_INCLUSIVE_MASK : 0;
+
+        element.objectValue = objVal;
+    }
+
+    public int getAttributeDataType(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        return attr.dataType;
+    }
+
+    public String getAttributeDefaultValue(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        return attr.defaultValue;
+    }
+
+    public String getAttributeDescription(String elementName, String attrName, Locale locale) {
+        findAttribute(elementName, attrName);
+        return getResourceString(elementName + "/" + attrName, locale);
+    }
+
+    public String[] getAttributeEnumerations(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if (attr.valueType != VALUE_ENUMERATION) {
+            throw new IllegalArgumentException("Attribute is not an enumeration!");
+        }
+
+        return attr.enumeratedValues.toArray(new String[attr.enumeratedValues.size()]);
+    }
+
+    public int getAttributeListMaxLength(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if (attr.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Attribute is not a list!");
+        }
+        return attr.listMaxLength;
+    }
+
+    public int getAttributeListMinLength(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if (attr.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Attribute is not a list!");
+        }
+        return attr.listMinLength;
+    }
+
+    public String getAttributeMaxValue(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if ((attr.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Attribute is not a range!");
+        }
+        return attr.maxValue;        
+    }
+
+    public String getAttributeMinValue(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        if ((attr.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Attribute is not a range!");
+        }
+        return attr.minValue;
+    }
+
+    public String[] getAttributeNames(String elementName) {
+        Element element = findElement(elementName);
+        return element.attributes.keySet().toArray(new String[element.attributes.size()]);
+    }
+
+    public int getAttributeValueType(String elementName, String attrName) {
+        Attlist attr = findAttribute(elementName, attrName);
+        return attr.valueType;                
+    }
+
+    public String[] getChildNames(String elementName) {
+        Element element = findElement(elementName);
+        if (element.childPolicy == CHILD_POLICY_EMPTY) { // Element cannot have children
+            return null;
+        }
+        return element.children.toArray(new String[element.children.size()]);
+    }
+
+    public int getChildPolicy(String elementName) {
+        Element element = findElement(elementName);
+        return element.childPolicy;
+    }
+
+    public String getElementDescription(String elementName, Locale locale) {
+        findElement(elementName); // Check if there is such element
+        return getResourceString(elementName, locale);
+    }
+
+    public int getElementMaxChildren(String elementName) {
+        Element element = findElement(elementName);
+        if (element.childPolicy != CHILD_POLICY_REPEAT) {
+            throw new IllegalArgumentException("Child policy is not CHILD_POLICY_REPEAT!");
+        }
+        return element.maxChildren;
+    }
+
+    public int getElementMinChildren(String elementName) {
+        Element element = findElement(elementName);
+        if (element.childPolicy != CHILD_POLICY_REPEAT) {
+            throw new IllegalArgumentException("Child policy is not CHILD_POLICY_REPEAT!");
+        }
+        return element.minChildren;
+    }
+
+    public int getObjectArrayMaxLength(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || v.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Not a list!");
+        }
+        return v.arrayMaxLength;
+    }
+
+    public int getObjectArrayMinLength(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || v.valueType != VALUE_LIST) {
+            throw new IllegalArgumentException("Not a list!");
+        }
+        return v.arrayMinLength;
+    }
+
+    public Class<?> getObjectClass(String elementName) {
+        ObjectValue v = findObjectValue(elementName);
+        return v.classType;
+    }
+
+    public Object getObjectDefaultValue(String elementName) {
+        ObjectValue v = findObjectValue(elementName);
+        return v.defaultValue;
+    }
+
+    public Object[] getObjectEnumerations(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || v.valueType != VALUE_ENUMERATION) {
+            throw new IllegalArgumentException("Not an enumeration!");
+        }
+        return v.enumeratedValues.toArray();
+    }
+
+    public Comparable<?> getObjectMaxValue(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || (v.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Not a range!");
+        }
+        return v.maxValue;
+    }
+
+    public Comparable<?> getObjectMinValue(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null || (v.valueType & VALUE_RANGE) == 0) {
+            throw new IllegalArgumentException("Not a range!");
+        }
+        return v.minValue;
+    }
+
+    public int getObjectValueType(String elementName) {
+        Element element = findElement(elementName);
+        if (element.objectValue == null) {
+            return VALUE_NONE;
+        }
+        return element.objectValue.valueType;
+    }
+
+    /**
+     * Gets the resource base name for locating ResourceBundles.
+     * 
+     * @return the current resource base name.
+     */
+    protected String getResourceBaseName() {
+        return resourceBaseName;
+    }
+
+    public String getRootName() {
+        return rootName;
+    }
+
+    /**
+     * Gets the standard format instance.
+     * 
+     * @return the IIOMetadataFormat instance.
+     */
+    public static IIOMetadataFormat getStandardFormatInstance() {
+        if (standardFormat == null) {
+            standardFormat = new IIOStandardMetadataFormat();
+        }
+
+        return standardFormat;
+    }
+
+    public boolean isAttributeRequired(String elementName, String attrName) {
+        return findAttribute(elementName, attrName).required;
+    }
+
+    /**
+     * Removes the specified attribute from the specified element. 
+     *  
+     * @param elementName the specified element name.
+     * @param attrName the specified attribute name.
+     */
+    protected void removeAttribute(String elementName, String attrName) {
+        Element element = findElement(elementName);
+        element.attributes.remove(attrName);
+    }
+
+    /**
+     * Removes the specified element from this format.
+     * 
+     * @param elementName the specified element name.
+     */
+    protected void removeElement(String elementName) {
+        Element element;
+        if ((element = elementHash.get(elementName)) != null) {
+            elementHash.remove(elementName);
+            for (Element e : elementHash.values()) {
+                e.children.remove(element.name);
+            }
+        }
+    }
+
+    /**
+     * Removes the object value from the specified element.
+     * 
+     * @param elementName the element name.
+     */
+    protected void removeObjectValue(String elementName) {
+        Element element = findElement(elementName);
+        element.objectValue = null;
+    }
+    
+    /**
+     * Sets a new base name for ResourceBundles containing 
+     * descriptions of elements and attributes for this format.
+     * 
+     * @param resourceBaseName the new resource base name.
+     */
+    protected void setResourceBaseName(String resourceBaseName) {
+        if (resourceBaseName == null) {
+            throw new IllegalArgumentException("resourceBaseName == null!");
+        }
+        this.resourceBaseName = resourceBaseName;
+    }
+
+    /**
+     * The Class Element.
+     */
+    @SuppressWarnings({"ClassWithoutConstructor"})
+    private class Element {
+        
+        /** The name. */
+        String name;
+
+        /** The children. */
+        ArrayList<String> children = new ArrayList<String>();
+        
+        /** The attributes. */
+        HashMap<String, Attlist> attributes = new HashMap<String, Attlist>();
+
+        /** The min children. */
+        int minChildren;
+        
+        /** The max children. */
+        int maxChildren;
+        
+        /** The child policy. */
+        int childPolicy;
+
+        /** The object value. */
+        ObjectValue objectValue;
+    }
+
+    /**
+     * The Class Attlist.
+     */
+    @SuppressWarnings({"ClassWithoutConstructor"})
+    private class Attlist {
+        
+        /** The name. */
+        String name;
+
+        /** The data type. */
+        int dataType;
+        
+        /** The required. */
+        boolean required;
+        
+        /** The list min length. */
+        int listMinLength;
+        
+        /** The list max length. */
+        int listMaxLength;
+        
+        /** The default value. */
+        String defaultValue;
+        
+        /** The enumerated values. */
+        List<String> enumeratedValues;
+        
+        /** The min value. */
+        String minValue;
+        
+        /** The max value. */
+        String maxValue;
+        
+        /** The min inclusive. */
+        boolean minInclusive;
+        
+        /** The max inclusive. */
+        boolean maxInclusive;
+
+        /** The value type. */
+        int valueType;
+    }
+
+    /**
+     * The Class ObjectValue.
+     */
+    @SuppressWarnings({"ClassWithoutConstructor"})
+    private class ObjectValue<T> {
+        
+        /** The class type. */
+        Class<T> classType;
+        
+        /** The array min length. */
+        int arrayMinLength;
+        
+        /** The array max length. */
+        int arrayMaxLength;
+        
+        /** The default value. */
+        T defaultValue;
+        
+        /** The enumerated values. */
+        List<? extends T> enumeratedValues;
+        
+        /** The min value. */
+        Comparable<? super T> minValue;
+        
+        /** The max value. */
+        Comparable<? super T> maxValue;
+        
+        /** The min inclusive. */
+        boolean minInclusive;
+        
+        /** The max inclusive. */
+        boolean maxInclusive;
+
+        /** The value type. */
+        int valueType;
+    }
+
+    /**
+     * Find element.
+     * 
+     * @param name the name
+     * 
+     * @return the element
+     */
+    private Element findElement(String name) {
+        Element element;
+        if ((element = elementHash.get(name)) == null) {
+            throw new IllegalArgumentException("element name is null or no such element: " + name);
+        }
+
+        return element;
+    }
+
+    /**
+     * Find attribute.
+     * 
+     * @param elementName the element name
+     * @param attributeName the attribute name
+     * 
+     * @return the attlist
+     */
+    private Attlist findAttribute(String elementName, String attributeName) {
+        Element element = findElement(elementName);
+        Attlist attribute;
+        if ((attribute = element.attributes.get(attributeName)) == null) {
+            throw new IllegalArgumentException("attribute name is null or no such attribute: " + attributeName);
+        }
+
+        return attribute;
+    }
+
+    /**
+     * Find object value.
+     * 
+     * @param elementName the element name
+     * 
+     * @return the object value
+     */
+    private ObjectValue findObjectValue(String elementName) {
+        Element element = findElement(elementName);
+        ObjectValue v = element.objectValue;
+        if (v == null) {
+            throw new IllegalArgumentException("No object within element");
+        }
+        return v;
+    }
+
+    /**
+     * Gets the resource string.
+     * 
+     * @param key the key
+     * @param locale the locale
+     * 
+     * @return the resource string
+     */
+    private String getResourceString(String key, Locale locale) {
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+
+        // Get the context class loader and try to locate the bundle with it first
+        ClassLoader contextClassloader = AccessController.doPrivileged(
+                new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
+                        return Thread.currentThread().getContextClassLoader();
+                    }
+        });
+
+        // Now try to get the resource bundle
+        ResourceBundle rb;
+        try {
+            rb = ResourceBundle.getBundle(resourceBaseName, locale, contextClassloader);
+        } catch (MissingResourceException e) {
+            try {
+                rb = ResourceBundle.getBundle(resourceBaseName, locale);
+            } catch (MissingResourceException e1) {
+                return null;
+            }
+        }
+
+        try {
+            return rb.getString(key);
+        } catch (MissingResourceException e) {
+            return null;
+        } catch (ClassCastException e) {
+            return null; // Not a string resource
+        }
+    }
+}
diff --git a/awt/javax/imageio/metadata/IIOMetadataNode.java b/awt/javax/imageio/metadata/IIOMetadataNode.java
new file mode 100644
index 0000000..d5ab7a5
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOMetadataNode.java
@@ -0,0 +1,675 @@
+/*
+ *  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.metadata;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+//???AWT
+//import org.w3c.dom.TypeInfo;
+//import org.w3c.dom.UserDataHandler;
+
+/**
+ * The Class IIOMetadataNode represents a node of the 
+ * (DOM-style) metadata tree.
+ */
+public class IIOMetadataNode implements Element, NodeList {
+
+    /** The node name. */
+    private String nodeName;
+    
+    /** The node value. */
+    private String nodeValue;
+    
+    /** The attributes. */
+    private IIOMetadataNodeList attrs = new IIOMetadataNodeList(new ArrayList<IIOMetadataNode>());
+
+    /** The parent node. */
+    private IIOMetadataNode parent;
+    
+    /** The first child node. */
+    private IIOMetadataNode firstChild;
+    
+    /** The last child node. */
+    private IIOMetadataNode lastChild;
+    
+    /** The previous sibling. */
+    private IIOMetadataNode previousSibling;
+    
+    /** The next sibling. */
+    private IIOMetadataNode nextSibling;
+
+    /** The number of children. */
+    private int nChildren;
+
+    /** The user object associated with this node. */
+    private Object userObject;
+
+    /** The text content of this node. */
+    private String textContent;
+
+    /**
+     * Instantiates a new empty node.
+     */
+    public IIOMetadataNode() {
+    }
+
+    /**
+     * Instantiates a new empty node with the specified name.
+     * 
+     * @param nodeName the node name
+     */
+    public IIOMetadataNode(String nodeName) {
+        this.nodeName = nodeName;
+    }
+
+    /**
+     * Instantiates a new IIOMetadataNode with the specified 
+     * name and value.
+     * 
+     * @param nodeName the node name
+     * @param nodeValue the node value
+     */
+    private IIOMetadataNode(String nodeName, String nodeValue) {
+        this.nodeName = nodeName;
+        this.nodeValue = nodeValue;
+    }
+
+    public String getTagName() {
+        return nodeName;
+    }
+
+    public String getAttribute(String name) {
+        Attr attrNode = (Attr) attrs.getNamedItem(name);
+        return (attrNode == null) ? "" : attrNode.getValue();
+    }
+
+    public void setAttribute(String name, String value) throws DOMException {
+        Attr attr = (Attr) attrs.getNamedItem(name);
+        if (attr != null) {
+            attr.setValue(value);
+        } else {
+            attrs.list.add(new IIOMetadataAttr(name, value, this));
+        }
+    }
+
+    public void removeAttribute(String name) throws DOMException {
+        IIOMetadataAttr attr = (IIOMetadataAttr) attrs.getNamedItem(name);
+        if (attr != null) {
+            attr.setOwnerElement(null);
+            attrs.list.remove(attr);
+        }
+    }
+
+    public Attr getAttributeNode(String name) {
+        return (Attr) attrs.getNamedItem(name);
+    }
+
+    public Attr setAttributeNode(Attr newAttr) throws DOMException {
+        // Check if this attribute is already in use.
+        Element owner = newAttr.getOwnerElement();
+        if (owner != null) {
+            if (owner == this) { // Replacing an attribute node by itself has no effect
+                return null;
+            } else {
+                throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, "Attribute is already in use");
+            }
+        }
+
+        String name = newAttr.getName();
+        Attr oldAttr = getAttributeNode(name);
+        if (oldAttr != null) {
+            removeAttributeNode(oldAttr);
+        }
+
+        IIOMetadataAttr iioAttr;
+        if (newAttr instanceof IIOMetadataAttr) {
+            iioAttr = (IIOMetadataAttr) newAttr;
+            iioAttr.setOwnerElement(this);
+        } else {
+            iioAttr = new IIOMetadataAttr(name, newAttr.getValue(), this);
+        }
+
+        attrs.list.add(iioAttr);
+
+        return oldAttr;
+    }
+
+    public Attr removeAttributeNode(Attr oldAttr) throws DOMException {
+        if (!attrs.list.remove(oldAttr)) { // Not found
+            throw new DOMException(DOMException.NOT_FOUND_ERR, "No such attribute!");
+        }
+
+        ((IIOMetadataAttr)oldAttr).setOwnerElement(null);
+
+        return oldAttr;
+    }
+
+    public NodeList getElementsByTagName(String name) {
+        ArrayList<IIOMetadataNode> nodes = new ArrayList<IIOMetadataNode>();
+
+        // Non-recursive tree walk
+        Node pos = this;
+
+        while (pos != null) {
+            if (pos.getNodeName().equals(name)) {
+                nodes.add((IIOMetadataNode)pos);
+            }
+
+            Node nextNode = pos.getFirstChild();
+
+            while (nextNode == null) {
+                if (pos == this) {
+                    break;
+                }
+
+                nextNode = pos.getNextSibling();
+
+                if (nextNode == null) {
+                    pos = pos.getParentNode();
+
+                    if (pos == null || pos == this) {
+                        nextNode = null;
+                        break;
+                    }
+                }
+            }
+            pos = nextNode;
+        }
+
+        return new IIOMetadataNodeList(nodes);
+    }
+
+    public String getAttributeNS(String namespaceURI, String localName) throws DOMException {
+        return getAttribute(localName);
+    }
+
+    public void setAttributeNS(String namespaceURI, String qualifiedName, String value) throws DOMException {
+        setAttribute(qualifiedName, value);
+    }
+
+    public void removeAttributeNS(String namespaceURI, String localName) throws DOMException {
+        removeAttribute(localName);
+    }
+
+    public Attr getAttributeNodeNS(String namespaceURI, String localName) throws DOMException {
+        return getAttributeNode(localName);
+    }
+
+    public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
+        return setAttributeNode(newAttr);
+    }
+
+    public NodeList getElementsByTagNameNS(String namespaceURI, String localName) throws DOMException {
+        return getElementsByTagName(localName);
+    }
+
+    public boolean hasAttribute(String name) {
+        return attrs.getNamedItem(name) != null;
+    }
+
+    public boolean hasAttributeNS(String namespaceURI, String localName) throws DOMException {
+        return hasAttribute(localName);
+    }
+
+    //???AWT
+    /*
+    public TypeInfo getSchemaTypeInfo() {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }*/
+
+    public void setIdAttribute(String name, boolean isId) throws DOMException {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public void setIdAttributeNS(String namespaceURI, String localName, boolean isId) throws DOMException {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public void setIdAttributeNode(Attr idAttr, boolean isId) throws DOMException {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public String getNodeName() {
+        return nodeName;
+    }
+
+    public String getNodeValue() throws DOMException {
+        return nodeValue;
+    }
+
+    public void setNodeValue(String nodeValue) throws DOMException {
+        this.nodeValue = nodeValue;
+    }
+
+    public short getNodeType() {
+        return ELEMENT_NODE;
+    }
+
+    public Node getParentNode() {
+        return parent;
+    }
+
+    public NodeList getChildNodes() {
+        return this;
+    }
+
+    public Node getFirstChild() {
+        return firstChild;
+    }
+
+    public Node getLastChild() {
+        return lastChild;
+    }
+
+    public Node getPreviousSibling() {
+        return previousSibling;
+    }
+
+    public Node getNextSibling() {
+        return nextSibling;
+    }
+
+    public NamedNodeMap getAttributes() {
+        return attrs;
+    }
+
+    public Document getOwnerDocument() {
+        return null;
+    }
+
+    public Node insertBefore(Node newChild, Node refChild) throws DOMException {
+        if (newChild == null) {
+            throw new IllegalArgumentException("newChild == null!");
+        }
+
+        IIOMetadataNode newIIOChild = (IIOMetadataNode) newChild;
+        IIOMetadataNode refIIOChild = (IIOMetadataNode) refChild;
+
+        newIIOChild.parent = this;
+
+        if (refIIOChild == null) {
+            newIIOChild.nextSibling = null;
+            newIIOChild.previousSibling = lastChild;
+
+            // Fix this node
+            lastChild = newIIOChild;
+            if (firstChild == null) {
+                firstChild = newIIOChild;
+            }
+        } else {
+            newIIOChild.nextSibling = refIIOChild;
+            newIIOChild.previousSibling = refIIOChild.previousSibling;
+
+            // Fix this node
+            if (firstChild == refIIOChild) {
+                firstChild = newIIOChild;
+            }
+
+            // Fix next node
+            if (refIIOChild != null) {
+                refIIOChild.previousSibling = newIIOChild;
+            }
+        }
+
+        // Fix prev node
+        if (newIIOChild.previousSibling != null) {
+            newIIOChild.previousSibling.nextSibling = newIIOChild;
+        }
+
+        nChildren++;
+
+        return newIIOChild;
+    }
+
+    public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
+        if (newChild == null) {
+            throw new IllegalArgumentException("newChild == null!");
+        }
+
+        IIOMetadataNode newIIOChild = (IIOMetadataNode) newChild;
+        IIOMetadataNode oldIIOChild = (IIOMetadataNode) oldChild;
+
+        IIOMetadataNode next = oldIIOChild.nextSibling;
+        IIOMetadataNode previous = oldIIOChild.previousSibling;
+
+        // Fix new node
+        newIIOChild.parent = this;
+        newIIOChild.nextSibling = next;
+        newIIOChild.previousSibling = previous;
+
+        // Fix this node
+        if (lastChild == oldIIOChild) {
+            lastChild = newIIOChild;
+        }
+        if (firstChild == oldIIOChild) {
+            firstChild = newIIOChild;
+        }
+
+        // Fix siblings
+        if (next != null) {
+            next.previousSibling = newIIOChild;
+        }
+        if (previous != null) {
+            previous.nextSibling = newIIOChild;
+        }
+
+        // Fix old child
+        oldIIOChild.parent = null;
+        oldIIOChild.nextSibling = next;
+        oldIIOChild.previousSibling = previous;
+
+        return oldIIOChild;
+    }
+
+    public Node removeChild(Node oldChild) throws DOMException {
+        if (oldChild == null) {
+            throw new IllegalArgumentException("oldChild == null!");
+        }
+
+        IIOMetadataNode oldIIOChild = (IIOMetadataNode) oldChild;
+
+        // Fix next and previous
+        IIOMetadataNode previous = oldIIOChild.previousSibling;
+        IIOMetadataNode next = oldIIOChild.nextSibling;
+
+        if (previous != null) {
+            previous.nextSibling = next;
+        }
+        if (next != null) {
+            next.previousSibling = previous;
+        }
+
+        // Fix this node
+        if (lastChild == oldIIOChild) {
+            lastChild = previous;
+        }
+        if (firstChild == oldIIOChild) {
+            firstChild = next;
+        }
+        nChildren--;
+
+        // Fix old child
+        oldIIOChild.parent = null;
+        oldIIOChild.previousSibling = null;
+        oldIIOChild.nextSibling = null;
+
+        return oldIIOChild;
+    }
+
+    public Node appendChild(Node newChild) throws DOMException {
+        return insertBefore(newChild, null);
+    }
+
+    public boolean hasChildNodes() {
+        return nChildren != 0;
+    }
+
+    public Node cloneNode(boolean deep) {
+        IIOMetadataNode cloned = new IIOMetadataNode(nodeName);
+        cloned.setUserObject(getUserObject());
+
+        if (deep) { // Clone recursively
+            IIOMetadataNode c = firstChild;
+            while (c != null) {
+                cloned.insertBefore(c.cloneNode(true), null);
+                c = c.nextSibling;
+            }
+        }
+
+        return cloned;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void normalize() {
+        // Do nothing
+    }
+
+    public boolean isSupported(String feature, String version) {
+        return false;
+    }
+
+    public String getNamespaceURI() {
+        return null;
+    }
+
+    public String getPrefix() {
+        return null;
+    }
+
+    public void setPrefix(String prefix) throws DOMException {
+        // Do nothing
+    }
+
+    public String getLocalName() {
+        return nodeName;
+    }
+
+    public boolean hasAttributes() {
+        return attrs.list.size() > 0;
+    }
+
+    public String getBaseURI() {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public short compareDocumentPosition(Node other) throws DOMException {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public String getTextContent() throws DOMException {
+        return textContent;
+    }
+
+    public void setTextContent(String textContent) throws DOMException {
+        this.textContent = textContent;
+    }
+
+    public boolean isSameNode(Node other) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public String lookupPrefix(String namespaceURI) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public boolean isDefaultNamespace(String namespaceURI) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public String lookupNamespaceURI(String prefix) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public boolean isEqualNode(Node arg) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public Object getFeature(String feature, String version) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    //???AWT
+    /*
+    public Object setUserData(String key, Object data, UserDataHandler handler) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }*/
+
+    public Object getUserData(String key) {
+        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+    }
+
+    public Node item(int index) {
+        if (index < 0 || index >= nChildren) {
+            return null;
+        }
+
+        Node n;
+        for (n = getFirstChild(); index > 0; index--) {
+            n = n.getNextSibling();
+        }
+
+        return n;
+    }
+
+    public int getLength() {
+        return nChildren;
+    }
+
+    /**
+     * Gets the user object associated with this node.
+     * 
+     * @return the user object associated with this node
+     */
+    public Object getUserObject() {
+        return userObject;
+    }
+
+    /**
+     * Sets the user object associated with this node.
+     * 
+     * @param userObject the new user object associated with this node
+     */
+    public void setUserObject(Object userObject) {
+        this.userObject = userObject;
+    }
+
+    /**
+     * The Class IIOMetadataAttr.
+     */
+    private class IIOMetadataAttr extends IIOMetadataNode implements Attr {
+        
+        /** The owner element. */
+        private Element ownerElement;
+
+        /**
+         * Instantiates a new iIO metadata attr.
+         * 
+         * @param name the name
+         * @param value the value
+         * @param owner the owner
+         */
+        public IIOMetadataAttr(String name, String value, Element owner) {
+            super(name, value);
+            this.ownerElement = owner;
+        }
+
+        public String getName() {
+            return getNodeName();
+        }
+
+        public boolean getSpecified() {
+            return true;
+        }
+
+        public String getValue() {
+            return nodeValue;
+        }
+
+        public void setValue(String value) throws DOMException {
+            nodeValue = value;
+        }
+
+        public Element getOwnerElement() {
+            return ownerElement;
+        }
+
+        /**
+         * Sets the owner element.
+         * 
+         * @param ownerElement the new owner element
+         */
+        public void setOwnerElement(Element ownerElement) {
+            this.ownerElement = ownerElement;
+        }
+
+        public boolean isId() {
+            throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
+        }
+
+        @Override
+        public short getNodeType() {
+            return ATTRIBUTE_NODE;
+        }
+    }
+
+    /**
+     * The Class IIOMetadataNodeList.
+     */
+    private class IIOMetadataNodeList implements NodeList, NamedNodeMap {
+        
+        /** The list. */
+        private List<IIOMetadataNode> list;
+
+        /**
+         * Instantiates a new iIO metadata node list.
+         * 
+         * @param list the list
+         */
+        IIOMetadataNodeList(List<IIOMetadataNode> list) {
+            this.list = list;
+        }
+
+        public Node item(int index) {
+            try {
+                return list.get(index);
+            } catch (IndexOutOfBoundsException e) {
+                return null;
+            }
+        }
+
+        public int getLength() {
+            return list.size();
+        }
+
+        public Node getNamedItem(String name) {
+            for(IIOMetadataNode node:list) {
+                if (name.equals(node.getNodeName())) {
+                    return node;
+                }
+            }
+            return null;
+        }
+
+        public Node setNamedItem(Node arg) throws DOMException {
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "This NamedNodeMap is read-only!");
+        }
+
+        public Node removeNamedItem(String name) throws DOMException {
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "This NamedNodeMap is read-only!");
+        }
+
+        public Node getNamedItemNS(String namespaceURI, String localName) throws DOMException {
+            return getNamedItem(localName);
+        }
+
+        public Node setNamedItemNS(Node arg) throws DOMException {
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "This NamedNodeMap is read-only!");
+        }
+
+        public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException {
+            throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "This NamedNodeMap is read-only!");
+        }
+    }
+}
diff --git a/awt/javax/imageio/metadata/IIOStandardMetadataFormat.java b/awt/javax/imageio/metadata/IIOStandardMetadataFormat.java
new file mode 100644
index 0000000..94d2125
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOStandardMetadataFormat.java
@@ -0,0 +1,316 @@
+/*
+ *  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.metadata;
+
+import javax.imageio.ImageTypeSpecifier;
+import java.util.ArrayList;
+
+/**
+ * The Class IIOStandardMetadataFormat describes the rules of the 
+ * standard metadata format.
+ */
+class IIOStandardMetadataFormat  extends IIOMetadataFormatImpl {
+    
+    /**
+     * Instantiates a new IIOStandardMetadataFormat.
+     */
+    public IIOStandardMetadataFormat() {
+        super(standardMetadataFormatName, CHILD_POLICY_SOME);
+        buildDTD();
+    }
+
+    @Override
+    public boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType) {
+        return true;
+    }
+
+    /**
+     * Builds the dtd that describes the standard metadata format.
+     */
+    private void buildDTD() {
+        // CHROMA
+        addElement("Chroma", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("ColorSpaceType", "Chroma", CHILD_POLICY_EMPTY);
+
+        ArrayList<String> values = new ArrayList<String>(27);
+        values.add("XYZ");
+        values.add("Lab");
+        values.add("Luv");
+        values.add("YCbCr");
+        values.add("Yxy");
+        values.add("YCCK");
+        values.add("PhotoYCC");
+        values.add("RGB");
+        values.add("GRAY");
+        values.add("HSV");
+        values.add("HLS");
+        values.add("CMYK");
+        values.add("CMY");
+        values.add("2CLR");
+        values.add("3CLR");
+        values.add("4CLR");
+        values.add("5CLR");
+        values.add("6CLR");
+        values.add("7CLR");
+        values.add("8CLR");
+        values.add("9CLR");
+        values.add("ACLR");
+        values.add("BCLR");
+        values.add("CCLR");
+        values.add("DCLR");
+        values.add("ECLR");
+        values.add("FCLR");
+        addAttribute("ColorSpaceType", "name", DATATYPE_STRING, true, null, values);
+
+        addElement("NumChannels", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("NumChannels", "value", DATATYPE_INTEGER, true, 0, Integer.MAX_VALUE); // list - why?
+
+        addElement("Gamma", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("Gamma", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("BlackIsZero", "Chroma", CHILD_POLICY_EMPTY);
+        addBooleanAttribute("BlackIsZero", "value", true, true);
+
+        addElement("Palette", "Chroma", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+        addElement("PaletteEntry", "Palette", CHILD_POLICY_EMPTY);
+        addAttribute("PaletteEntry", "index", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "red", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "green", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "blue", DATATYPE_INTEGER, true, null);
+        addAttribute("PaletteEntry", "alpha", DATATYPE_INTEGER, false, "255");
+
+        addElement("BackgroundIndex", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("BackgroundIndex", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("BackgroundColor", "Chroma", CHILD_POLICY_EMPTY);
+        addAttribute("BackgroundColor", "red", DATATYPE_INTEGER, true, null);
+        addAttribute("BackgroundColor", "green", DATATYPE_INTEGER, true, null);
+        addAttribute("BackgroundColor", "blue", DATATYPE_INTEGER, true, null);
+
+        // COMPRESSION
+        addElement("Compression", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("CompressionTypeName", "Compression", CHILD_POLICY_EMPTY);
+        addAttribute("CompressionTypeName", "value", DATATYPE_STRING, true, null);
+
+        addElement("Lossless", "Compression", CHILD_POLICY_EMPTY);
+        addBooleanAttribute("Lossless", "value", true, true);
+
+        addElement("NumProgressiveScans", "Compression", CHILD_POLICY_EMPTY);
+        addAttribute("NumProgressiveScans", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("BitRate", "Compression", CHILD_POLICY_EMPTY);
+        addAttribute("BitRate", "value", DATATYPE_FLOAT, true, null);
+
+        // DATA
+        addElement("Data", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("PlanarConfiguration", "Data", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(4);
+        values.add("PixelInterleaved");
+        values.add("PlaneInterleaved");
+        values.add("LineInterleaved");
+        values.add("TileInterleaved");
+        addAttribute("PlanarConfiguration", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("SampleFormat", "Data", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(4);
+        values.add("SignedIntegral");
+        values.add("UnsignedIntegral");
+        values.add("Real");
+        values.add("Index");
+        addAttribute("SampleFormat", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("BitsPerSample", "Data", CHILD_POLICY_EMPTY);
+        addAttribute("BitsPerSample", "value", DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE); // list
+
+        addElement("SignificantBitsPerSample", "Data", CHILD_POLICY_EMPTY);
+        addAttribute(
+                "SignificantBitsPerSample", "value",
+                DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE
+        ); // list
+
+        addElement("SampleMSB", "Data", CHILD_POLICY_EMPTY);
+        addAttribute("SampleMSB", "value", DATATYPE_INTEGER, true, 1, Integer.MAX_VALUE); // list
+
+        // DIMENSION
+        addElement("Dimension", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("PixelAspectRatio", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("PixelAspectRatio", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("ImageOrientation", "Dimension", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(8);
+        values.add("Normal");
+        values.add("Rotate90");
+        values.add("Rotate180");
+        values.add("Rotate270");
+        values.add("FlipH");
+        values.add("FlipV");
+        values.add("FlipHRotate90");
+        values.add("FlipVRotate90");
+        addAttribute("ImageOrientation", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("HorizontalPixelSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPixelSize", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("VerticalPixelSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPixelSize", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("HorizontalPhysicalPixelSpacing", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPhysicalPixelSpacing", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("VerticalPhysicalPixelSpacing", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPhysicalPixelSpacing", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("HorizontalPosition", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPosition", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("VerticalPosition", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPosition", "value", DATATYPE_FLOAT, true, null);
+
+        addElement("HorizontalPixelOffset", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalPixelOffset", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("VerticalPixelOffset", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalPixelOffset", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("HorizontalScreenSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("HorizontalScreenSize", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("VerticalScreenSize", "Dimension", CHILD_POLICY_EMPTY);
+        addAttribute("VerticalScreenSize", "value", DATATYPE_INTEGER, true, null);
+
+        // DOCUMENT
+        addElement("Document", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("FormatVersion", "Document", CHILD_POLICY_EMPTY);
+        addAttribute("FormatVersion", "value", DATATYPE_STRING, true, null);
+
+        addElement("SubimageInterpretation", "Document", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(14);
+        values.add("Standalone");
+        values.add("SinglePage");
+        values.add("FullResolution");
+        values.add("ReducedResolution");
+        values.add("PyramidLayer");
+        values.add("Preview");
+        values.add("VolumeSlice");
+        values.add("ObjectView");
+        values.add("Panorama");
+        values.add("AnimationFrame");
+        values.add("TransparencyMask");
+        values.add("CompositingLayer");
+        values.add("SpectralSlice");
+        values.add("Unknown");
+        addAttribute("SubimageInterpretation", "value", DATATYPE_STRING, true, null, values);
+
+        addElement("ImageCreationTime", "Document", CHILD_POLICY_EMPTY);
+        addAttribute("ImageCreationTime", "year", DATATYPE_INTEGER, true, null);
+        addAttribute(
+                "ImageCreationTime", "month",
+                DATATYPE_INTEGER, true, null, "1", "12", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "day",
+                DATATYPE_INTEGER, true, null, "1", "31", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "hour",
+                DATATYPE_INTEGER, false, "0", "0", "23", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "minute",
+                DATATYPE_INTEGER, false, "0", "0", "59", true, true
+        );
+        addAttribute(
+                "ImageCreationTime", "second",
+                DATATYPE_INTEGER, false, "0", "0", "60", true, true
+        );
+
+        addElement("ImageModificationTime", "Document", CHILD_POLICY_EMPTY);
+        addAttribute("ImageModificationTime", "year", DATATYPE_INTEGER, true, null);
+        addAttribute(
+                "ImageModificationTime", "month",
+                DATATYPE_INTEGER, true, null, "1", "12", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "day",
+                DATATYPE_INTEGER, true, null, "1", "31", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "hour",
+                DATATYPE_INTEGER, false, "0", "0", "23", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "minute",
+                DATATYPE_INTEGER, false, "0", "0", "59", true, true
+        );
+        addAttribute(
+                "ImageModificationTime", "second",
+                DATATYPE_INTEGER, false, "0", "0", "60", true, true
+        );
+
+        // TEXT
+        addElement("Text", standardMetadataFormatName, 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+
+        addElement("TextEntry", "Text", CHILD_POLICY_EMPTY);
+        addAttribute("TextEntry", "keyword", DATATYPE_STRING, false, null);
+        addAttribute("TextEntry", "value", DATATYPE_STRING, true, null);
+        addAttribute("TextEntry", "language", DATATYPE_STRING, false, null);
+        addAttribute("TextEntry", "encoding", DATATYPE_STRING, false, null);
+        values = new ArrayList<String>(5);
+        values.add("none");
+        values.add("lzw");
+        values.add("zip");
+        values.add("bzip");
+        values.add("other");
+        addAttribute("TextEntry", "compression", DATATYPE_STRING, false, "none", values);
+
+        // TRANSPARENCY
+        addElement("Transparency", standardMetadataFormatName, CHILD_POLICY_SOME);
+
+        addElement("Alpha", "Transparency", CHILD_POLICY_EMPTY);
+        values = new ArrayList<String>(3);
+        values.add("none");
+        values.add("premultiplied");
+        values.add("nonpremultiplied");
+        addAttribute("Alpha", "value", DATATYPE_STRING, false, "none", values);
+
+        addElement("TransparentIndex", "Transparency", CHILD_POLICY_EMPTY);
+        addAttribute("TransparentIndex", "value", DATATYPE_INTEGER, true, null);
+
+        addElement("TransparentColor", "Transparency", CHILD_POLICY_EMPTY);
+        addAttribute("TransparentColor", "value", DATATYPE_INTEGER, true, 0, Integer.MAX_VALUE);
+
+        addElement("TileTransparencies", "Transparency", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+
+        addElement("TransparentTile", "TileTransparencies", CHILD_POLICY_EMPTY);
+        addAttribute("TransparentTile", "x", DATATYPE_INTEGER, true, null);
+        addAttribute("TransparentTile", "y", DATATYPE_INTEGER, true, null);
+
+        addElement("TileOpacities", "Transparency", 0, Integer.MAX_VALUE); // CHILD_POLICY_REPEAT
+
+        addElement("OpaqueTile", "TileOpacities", CHILD_POLICY_EMPTY);
+        addAttribute("OpaqueTile", "x", DATATYPE_INTEGER, true, null);
+        addAttribute("OpaqueTile", "y", DATATYPE_INTEGER, true, null);
+    }
+}
+
diff --git a/awt/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties b/awt/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties
new file mode 100644
index 0000000..d185808
--- /dev/null
+++ b/awt/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties
@@ -0,0 +1,133 @@
+# 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.
+
+# Descriptions of elements and attributes of the plugin neutral metadata format
+# (see IIOStandardMetadataFormat)
+
+# Messages for EN locale
+Chroma=Chroma (color) information
+ColorSpaceType=The raw color space of the image
+ColorSpaceType/name=The raw color space of the image
+NumChannels=The number of channels in the raw image, including alpha
+NumChannels/value=The number of channels in the raw image, including alpha
+Gamma=The image gamma
+Gamma/value=The image gamma
+BlackIsZero=True if smaller values represent darker shades
+BlackIsZero/value=True if smaller values represent darker shades
+Palette=Palette-color information
+PaletteEntry=A palette entry
+PaletteEntry/index=The index of the palette entry
+PaletteEntry/red=The red value for the palette entry
+PaletteEntry/green=The green value for the palette entry
+PaletteEntry/blue=The blue value for the palette entry
+PaletteEntry/alpha=The alpha value for the palette entry
+BackgroundIndex=A palette index to be used as a background
+BackgroundIndex/value=A palette index to be used as a background
+BackgroundColor=An RGB triple to be used as a background
+BackgroundColor/red=The red background value
+BackgroundColor/green=The green background value
+BackgroundColor/blue=The blue background value
+
+Compression=Compression information
+CompressionTypeName=The name of the compression scheme in use
+CompressionTypeName/value=The name of the compression scheme in use
+Lossless=True if the compression scheme is lossless
+Lossless/value=True if the compression scheme is lossless
+NumProgressiveScans=The number of progressive scans used in the image encoding
+NumProgressiveScans/value=The number of progressive scans used in the image encoding
+BitRate=The estimated bit rate of the compression scheme
+BitRate/value=The estimated bit rate of the compression scheme
+
+Data=Information on the image layout
+PlanarConfiguration=The organization of image samples in the stream
+PlanarConfiguration/value=The organization of image samples in the stream
+SampleFormat=The numeric format of image samples
+SampleFormat/value=The numeric format of image samples
+BitsPerSample=The number of bits per sample
+BitsPerSample/value=A list of integers, one per channel
+SignificantBitsPerSample=The number of significant bits per sample
+SignificantBitsPerSample/value=A list of integers, one per channel
+SampleMSB=The position of the most significant bit of each sample
+SampleMSB/value=A list of integers, one per channel
+
+Dimension=Dimension information
+PixelAspectRatio=The width of a pixel divided by its height
+PixelAspectRatio/value=The width of a pixel divided by its height
+ImageOrientation=The desired orientation of the image in terms of flips and counter-clockwise rotations
+ImageOrientation/value=The desired orientation of the image in terms of flips and counter-clockwise rotations
+HorizontalPixelSize=The width of a pixel, in millimeters, as it should be rendered on media
+HorizontalPixelSize/value=The width of a pixel, in millimeters, as it should be rendered on media
+VerticalPixelSize=The height of a pixel, in millimeters, as it should be rendered on media
+VerticalPixelSize/value=The height of a pixel, in millimeters, as it should be rendered on media
+HorizontalPhysicalPixelSpacing=The horizontal distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+HorizontalPhysicalPixelSpacing/value=The horizontal distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+VerticalPhysicalPixelSpacing=The vertical distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+VerticalPhysicalPixelSpacing/value=The vertical distance in the subject of the image, in millimeters, represented by one pixel at the center of the image
+HorizontalPosition=The horizontal position, in millimeters, where the image should be rendered on media
+HorizontalPosition/value=The horizontal position, in millimeters, where the image should be rendered on media
+VerticalPosition=The vertical position, in millimeters, where the image should be rendered on media
+VerticalPosition/value=The vertical position, in millimeters, where the image should be rendered on media
+HorizontalPixelOffset=The horizonal position, in pixels, where the image should be rendered onto a raster display
+HorizontalPixelOffset/value=The horizonal position, in pixels, where the image should be rendered onto a raster display
+VerticalPixelOffset=The vertical position, in pixels, where the image should be rendered onto a raster display
+VerticalPixelOffset/value=The vertical position, in pixels, where the image should be rendered onto a raster display
+HorizontalScreenSize=The width, in pixels, of the raster display into which the image should be rendered
+HorizontalScreenSize/value=The width, in pixels, of the raster display into which the image should be rendered
+VerticalScreenSize=The height, in pixels, of the raster display into which the image should be rendered
+VerticalScreenSize/value=The height, in pixels, of the raster display into which the image should be rendered
+
+Document=Document information
+FormatVersion=The version of the format used by the stream
+FormatVersion/value=The version of the format used by the stream
+SubimageInterpretation=The interpretation of this image in relation to the other images stored in the same stream
+SubimageInterpretation/value=The interpretation of this image in relation to the other images stored in the same stream
+ImageCreationTime=The time of image creation
+ImageCreationTime/year=The full year (e.g., 1967, not 67)
+ImageCreationTime/month=The month, with January = 1
+ImageCreationTime/day=The day of the month
+ImageCreationTime/hour=The hour from 0 to 23
+ImageCreationTime/minute=The minute from 0 to 59
+ImageCreationTime/second=The second from 0 to 60 (60 = leap second)
+ImageModificationTime=The time of the last image modification
+ImageModificationTime/year=The full year (e.g., 1967, not 67)
+ImageModificationTime/month=The month, with January = 1
+ImageModificationTime/day=The day of the month
+ImageModificationTime/hour=The hour from 0 to 23
+ImageModificationTime/minute=The minute from 0 to 59
+ImageModificationTime/second=The second from 0 to 60 (60 = leap second)
+
+Text=Text information
+TextEntry=A text entry
+TextEntry/keyword=A keyword associated with the text entry
+TextEntry/value=the text entry
+TextEntry/language=The language of the text
+TextEntry/encoding=The encoding of the text
+TextEntry/compression=The method used to compress the text
+
+Transparency=Transparency information
+Alpha=The type of alpha information contained in the image
+Alpha/value=The type of alpha information contained in the image
+TransparentIndex=A palette index to be treated as transparent
+TransparentIndex/value=A palette index to be treated as transparent
+TransparentColor=An RGB color to be treated as transparent
+TransparentColor/value=An RGB color to be treated as transparent
+TileTransparencies=A list of completely transparent tiles
+TransparentTile=The index of a completely transparent tile
+TransparentTile/x=The tile's X index
+TransparentTile/y=The tile's Y index
+TileOpacities=A list of completely opaque tiles
+OpaqueTile=The index of a completely opaque tile
+OpaqueTile/x=The tile's X index
+OpaqueTile/y=The tile's Y index
diff --git a/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java b/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java
new file mode 100644
index 0000000..0cd44db
--- /dev/null
+++ b/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java
@@ -0,0 +1,75 @@
+/*
+ *  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.plugins.bmp;
+
+import javax.imageio.ImageWriteParam;
+import java.util.Locale;
+
+/**
+ * The BMPImageWriteParam class allows encoding an image in
+ * BMP format.
+ */
+public class BMPImageWriteParam extends ImageWriteParam {
+    
+    /** The top down. */
+    private boolean topDown; // Default is bottom-up
+
+    /**
+     * Instantiates a new BMPImageWriteParam with default values of all
+     * parameters.
+     */
+    public BMPImageWriteParam() {
+        this(null);
+    }
+
+    /**
+     * Instantiates a new BMPImageWriteParam with the specified Locale.
+     * 
+     * @param locale the specified Locale.
+     */
+    public BMPImageWriteParam(Locale locale) {
+        super(locale);
+
+        // Set the compression
+        canWriteCompressed = true;
+        compressionTypes = new String[] {"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS"};
+        compressionType = compressionTypes[0]; 
+    }
+
+    /**
+     * Sets true if the data will be written in a top-down order, 
+     * false otherwise.
+     * 
+     * @param topDown the new top-down value. 
+     */
+    public void setTopDown(boolean topDown) {
+        this.topDown = topDown;
+    }
+
+    /**
+     * Returns true if the data is written in top-down order, false
+     * otherwise.
+     * 
+     * @return true if the data is written in top-down order, false
+     * otherwise.
+     */
+    public boolean isTopDown() {
+        return topDown;
+    }
+}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java b/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
new file mode 100644
index 0000000..398c960
--- /dev/null
+++ b/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
@@ -0,0 +1,213 @@
+/*
+ *  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.plugins.jpeg;
+
+/**
+ * The JPEGHuffmanTable class represents a single JPEG Huffman table. 
+ * It contains the standard tables from the JPEG specification.
+ */
+public class JPEGHuffmanTable {
+    
+    /** The standard DC luminance Huffman table . */
+    public static final JPEGHuffmanTable StdDCLuminance = new JPEGHuffmanTable(
+            new short[] {0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+            new short[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0A, 0x0B},
+            false
+    );
+
+    /** The standard DC chrominance Huffman table. */
+    public static final JPEGHuffmanTable StdDCChrominance = new JPEGHuffmanTable(
+            new short[] {0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
+            new short[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0A, 0x0B},
+            false
+    );
+
+    /** The standard AC luminance Huffman table. */
+    public static final JPEGHuffmanTable StdACLuminance = new JPEGHuffmanTable(
+            new short[] {0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7D},
+            new short[] {
+                    0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
+                    0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08,
+                    0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72,
+                    0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28,
+                    0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45,
+                    0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+                    0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75,
+                    0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+                    0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3,
+                    0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6,
+                    0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
+                    0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
+                    0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4,
+                    0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
+            },
+            false
+    );
+
+    /** 
+     * The standard AC chrominance Huffman table. */
+    public static final JPEGHuffmanTable StdACChrominance = new JPEGHuffmanTable(
+            new short[] {0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77},
+            new short[] {
+                    0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
+                    0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+                    0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1,
+                    0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26,
+                    0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
+                    0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+                    0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74,
+                    0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+                    0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
+                    0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4,
+                    0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+                    0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA,
+                    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4,
+                    0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
+            },
+            false
+    );
+
+    /** The lengths. */
+    private short lengths[];
+    
+    /** The values. */
+    private short values[];
+
+    /**
+     * Instantiates a new jPEG huffman table.
+     * 
+     * @param lengths the lengths
+     * @param values the values
+     * @param copy the copy
+     */
+    JPEGHuffmanTable(short[] lengths, short[] values, boolean copy) {
+        // Construction of standard tables without checks
+        // The third param is dummy
+        // Could be also used for copying of the existing tables
+        this.lengths = lengths;
+        this.values = values;
+    }
+
+    /**
+     * Instantiates a new JPEGHuffmanTable.
+     * 
+     * @param lengths the array of shorts lengths.
+     * @param values the array of shorts containing 
+     * the values in order of increasing code length.
+     */
+    public JPEGHuffmanTable(short[] lengths, short[] values) {
+        if (lengths == null) {
+            throw new IllegalArgumentException("lengths array is null!");
+        }
+        if (values == null) {
+            throw new IllegalArgumentException("values array is null!");
+        }
+        if (lengths.length > 16) { // According to the spec
+            throw new IllegalArgumentException("lengths array is too long!");
+        }
+        if (values.length > 256) { // According to the spec
+            throw new IllegalArgumentException("values array is too long");
+        }
+        for (short length : lengths) {
+            if (length < 0) {
+                throw new IllegalArgumentException("Values in lengths array must be non-negative.");
+            }
+        }
+        for (short value : values) {
+            if (value < 0) {
+                throw new IllegalArgumentException("Values in values array must be non-negative.");
+            }
+        }
+
+        checkHuffmanTable(lengths, values);
+
+        this.lengths = new short[lengths.length];
+        this.values = new short[values.length];
+        System.arraycopy(lengths, 0, this.lengths, 0, lengths.length);
+        System.arraycopy(values, 0, this.values, 0, values.length);
+    }
+
+    /**
+     * Gets an array of lengths in the Huffman table.
+     * 
+     * @return the array of short values representing the
+     * length values in the Huffman table.
+     */
+    public short[] getLengths() {
+        short newLengths[] = new short[lengths.length];
+        System.arraycopy(lengths, 0, newLengths, 0, lengths.length);
+        return newLengths;
+    }
+
+    /**
+     * Gets an array of values represented by increasing length of 
+     * their codes.
+     * 
+     * @return the array of values.
+     */
+    public short[] getValues() {
+        short newValues[] = new short[values.length];
+        System.arraycopy(values, 0, newValues, 0, values.length);
+        return newValues;
+    }
+
+    /**
+     * Check huffman table.
+     * 
+     * @param lengths the lengths
+     * @param values the values
+     */
+    private static void checkHuffmanTable(short[] lengths, short[] values) {
+        int numLeaves = 0;
+        int possibleLeaves = 2;
+        for (short length : lengths) {
+            numLeaves += length;
+            possibleLeaves -= length;
+            if (possibleLeaves < 0) {
+                throw new IllegalArgumentException("Invalid Huffman table provided, lengths are incorrect.");
+            }
+            possibleLeaves <<= 1;
+        }
+
+        if (values.length != numLeaves) {
+            throw new IllegalArgumentException("Invalid Huffman table provided, sum of lengths != values.");
+        }
+    }
+
+    /**
+     * Returns the string representation of this JPEGHuffmanTable object.
+     * 
+     * @return the string representation of this JPEGHuffmanTable object.
+     */
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("JPEGHuffmanTable:\nlengths:");
+        for (short length : lengths) {
+            sb.append(' ').append(length);
+        }
+
+        sb.append("\nvalues:");
+        for (short value : values) {
+            sb.append(' ').append(value);
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGImageReadParam.java b/awt/javax/imageio/plugins/jpeg/JPEGImageReadParam.java
new file mode 100644
index 0000000..dd08d51
--- /dev/null
+++ b/awt/javax/imageio/plugins/jpeg/JPEGImageReadParam.java
@@ -0,0 +1,116 @@
+/*
+ *  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.plugins.jpeg;
+
+import javax.imageio.ImageReadParam;
+
+/**
+ * The JPEGImageReadParam class provides functionality to set Huffman tables 
+ * and quantization tables when using the JPEG reader plug-in.
+ */
+public class JPEGImageReadParam extends ImageReadParam {
+    
+    /** The q tables. */
+    private JPEGQTable qTables[];
+    
+    /** The dc huffman tables. */
+    private JPEGHuffmanTable dcHuffmanTables[];
+    
+    /** The ac huffman tables. */
+    private JPEGHuffmanTable acHuffmanTables[];
+
+    /**
+     * Instantiates a new JPEGImageReadParam.
+     */
+    public JPEGImageReadParam() {
+    }
+
+    /**
+     * Returns true if tables are set, false otherwise.
+     * 
+     * @return true if tables are set, false otherwise.
+     */
+    public boolean areTablesSet() {
+        return qTables != null;
+    }
+
+    /**
+     * Sets the quantization and Huffman tables for using in 
+     * decoding streams.
+     * 
+     * @param qTables the quantization tables.
+     * @param DCHuffmanTables the standart DC Huffman tables.
+     * @param ACHuffmanTables the standart AC huffman tables.
+     */
+    public void setDecodeTables(
+            JPEGQTable[] qTables,
+            JPEGHuffmanTable[] DCHuffmanTables,
+            JPEGHuffmanTable[] ACHuffmanTables
+    ) {
+        if (qTables == null || DCHuffmanTables == null || ACHuffmanTables == null) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+        if(DCHuffmanTables.length != ACHuffmanTables.length) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+        if (qTables.length > 4 || DCHuffmanTables.length > 4) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+
+        // Do the shallow copy, it should be enough
+        this.qTables = qTables.clone();
+        dcHuffmanTables = DCHuffmanTables.clone();
+        acHuffmanTables = ACHuffmanTables.clone();
+    }
+
+    /**
+     * Unset all decoded tables.
+     */
+    public void unsetDecodeTables() {
+        qTables = null;
+        dcHuffmanTables = null;
+        acHuffmanTables = null;
+    }
+
+    /**
+     * Gets the quantization tables.
+     * 
+     * @return the quantization tables, or null.
+     */
+    public JPEGQTable[] getQTables() {
+        return qTables == null ? null : qTables.clone();
+    }
+
+    /**
+     * Gets the DC Huffman tables.
+     * 
+     * @return the DC Huffman tables which are set, or null.
+     */
+    public JPEGHuffmanTable[] getDCHuffmanTables() {
+        return dcHuffmanTables == null ? null : dcHuffmanTables.clone();
+    }
+
+    /**
+     * Gets the AC Huffman tables.
+     * 
+     * @return the AC Huffman tables which are set, or null.
+     */
+    public JPEGHuffmanTable[] getACHuffmanTables() {
+        return acHuffmanTables == null ? null : acHuffmanTables.clone();
+    }    
+}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java b/awt/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java
new file mode 100644
index 0000000..34a3cd9
--- /dev/null
+++ b/awt/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java
@@ -0,0 +1,193 @@
+/*
+ *  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.plugins.jpeg;
+
+import org.apache.harmony.x.imageio.plugins.jpeg.JPEGConsts;
+
+import javax.imageio.ImageWriteParam;
+import java.util.Locale;
+
+/**
+ * The JPEGImageWriteParam class allows to set JPEG Huffman tables 
+ * and quantization when using the JPEG writer plug-in.
+ */
+public class JPEGImageWriteParam extends ImageWriteParam {
+    
+    /** The Constant COMP_QUALITY_VALUES. */
+    private static final float[] COMP_QUALITY_VALUES = {0.05f, 0.75f, 0.95f};
+    
+    /** The Constant COMP_QUALITY_DESCRIPTIONS. */
+    private static final String[] COMP_QUALITY_DESCRIPTIONS = {
+            "Minimum useful",
+            "Visually lossless",
+            "Maximum useful"
+    };
+
+    /** The q tables. */
+    private JPEGQTable[] qTables;
+    
+    /** The dc huffman tables. */
+    private JPEGHuffmanTable[] dcHuffmanTables;
+    
+    /** The ac huffman tables. */
+    private JPEGHuffmanTable[] acHuffmanTables;
+
+    /** The optimize huffman tables. */
+    private boolean optimizeHuffmanTables;
+
+    /**
+     * Instantiates a new JPEGImageWriteParam object with 
+     * the specified Locale.
+     * 
+     * @param locale the Locale.
+     */
+    public JPEGImageWriteParam(Locale locale) {
+        super(locale);
+
+        canWriteProgressive = true;
+        progressiveMode = ImageWriteParam.MODE_DISABLED;
+
+        canWriteCompressed = true;
+        compressionTypes = new String[]{"JPEG"};
+        compressionType = compressionTypes[0]; 
+        compressionQuality = JPEGConsts.DEFAULT_JPEG_COMPRESSION_QUALITY;
+    }
+
+    /**
+     * Returns true if tables are set, false otherwise.
+     * 
+     * @return true if tables are set, false otherwise.
+     */
+    public boolean areTablesSet() {
+        return qTables != null;
+    }
+
+    /**
+     * Sets the quantization and Huffman tables for using in 
+     * encoding streams.
+     * 
+     * @param qTables the quantization tables.
+     * @param DCHuffmanTables the standart DC Huffman tables.
+     * @param ACHuffmanTables the standart AC huffman tables.
+     */
+    public void setEncodeTables(
+            JPEGQTable[] qTables,
+            JPEGHuffmanTable[] DCHuffmanTables,
+            JPEGHuffmanTable[] ACHuffmanTables
+    ) {
+        if (qTables == null || DCHuffmanTables == null || ACHuffmanTables == null) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+        if(DCHuffmanTables.length != ACHuffmanTables.length) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+        if (qTables.length > 4 || DCHuffmanTables.length > 4) {
+            throw new IllegalArgumentException("Invalid JPEG table arrays");
+        }
+
+        // Do the shallow copy, it should be enough
+        this.qTables = qTables.clone();
+        dcHuffmanTables = DCHuffmanTables.clone();
+        acHuffmanTables = ACHuffmanTables.clone();
+    }
+
+    /**
+     * Unset all encoded tables.
+     */
+    public void unsetEncodeTables() {
+        qTables = null;
+        dcHuffmanTables = null;
+        acHuffmanTables = null;
+    }
+
+    /**
+     * Gets the DC Huffman tables.
+     * 
+     * @return the DC Huffman tables which are set, or null.
+     */
+    public JPEGHuffmanTable[] getDCHuffmanTables() {
+        return dcHuffmanTables == null ? null : dcHuffmanTables.clone();
+    }
+
+    /**
+     * Gets the AC Huffman tables.
+     * 
+     * @return the AC Huffman tables which are set, or null.
+     */
+    public JPEGHuffmanTable[] getACHuffmanTables() {
+        return acHuffmanTables == null ? null : acHuffmanTables.clone();
+    }
+
+    /**
+     * Gets the quantization tables.
+     * 
+     * @return the quantization tables, or null.
+     */
+    public JPEGQTable[] getQTables() {
+        return qTables == null ? null : qTables.clone();
+    }
+
+    @Override
+    public String[] getCompressionQualityDescriptions() {
+        super.getCompressionQualityDescriptions();
+        return COMP_QUALITY_DESCRIPTIONS.clone();
+    }
+
+    @Override
+    public float[] getCompressionQualityValues() {
+        super.getCompressionQualityValues();
+        return COMP_QUALITY_VALUES.clone();
+    }
+
+    /**
+     * Sets the flag indicated that the writer will generate optimized 
+     * Huffman tables for the image as part of the writing process.
+     * 
+     * @param optimize the flag of optimizing huffman tables.
+     */
+    public void setOptimizeHuffmanTables(boolean optimize) {
+        optimizeHuffmanTables = optimize;
+    }
+
+    /**
+     * Returns true if the writer generates optimized Huffman tables,
+     * false otherwise.
+     * 
+     * @return the true if the writer generates optimized Huffman tables,
+     * false otherwise.
+     */
+    public boolean getOptimizeHuffmanTables() {
+        return optimizeHuffmanTables;
+    }
+
+    @Override
+    public boolean isCompressionLossless() {
+        if (getCompressionMode() != MODE_EXPLICIT) {
+            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
+        }
+        return false;
+    }
+
+    @Override
+    public void unsetCompression() {
+        if (getCompressionMode() != MODE_EXPLICIT) {
+            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
+        }
+        compressionQuality = JPEGConsts.DEFAULT_JPEG_COMPRESSION_QUALITY;
+    }
+}
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGQTable.java b/awt/javax/imageio/plugins/jpeg/JPEGQTable.java
new file mode 100644
index 0000000..0c5b37e
--- /dev/null
+++ b/awt/javax/imageio/plugins/jpeg/JPEGQTable.java
@@ -0,0 +1,162 @@
+/*
+ *  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.plugins.jpeg;
+
+/**
+ * The JPEGQTable class represents a single JPEG quantization table 
+ * and provides for the standard tables taken from the JPEG specification.
+ */
+public class JPEGQTable {
+
+    /** The Constant SIZE. */
+    private final static int SIZE = 64;
+    
+    /** The Constant BASELINE_MAX. */
+    private final static int BASELINE_MAX = 255;
+    
+    /** The Constant MAX. */
+    private final static int MAX = 32767;
+
+
+    /** The table. */
+    private int[] theTable;
+
+    /*
+     * K1 & K2 tables can be found in the JPEG format specification 
+     * at http://www.w3.org/Graphics/JPEG/itu-t81.pdf
+     */
+
+    /** The Constant K1LumTable. */
+    private static final int[] K1LumTable = new int[] {
+        16,  11,  10,  16,  24,  40,  51,  61,
+        12,  12,  14,  19,  26,  58,  60,  55,
+        14,  13,  16,  24,  40,  57,  69,  56,
+        14,  17,  22,  29,  51,  87,  80,  62,
+        18,  22,  37,  56,  68,  109, 103, 77,
+        24,  35,  55,  64,  81,  104, 113, 92,
+        49,  64,  78,  87,  103, 121, 120, 101,
+        72,  92,  95,  98,  112, 100, 103, 99
+    };
+
+    /** The Constant K2ChrTable. */
+    private static final int[] K2ChrTable = new int[] {
+        17,  18,  24,  47,  99,  99,  99,  99,
+        18,  21,  26,  66,  99,  99,  99,  99,
+        24,  26,  56,  99,  99,  99,  99,  99,
+        47,  66,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99
+    };
+
+    /** 
+     * The K1Luminance indicates standart table K.1 from JPEG
+     * specification and produces "good" quality output. 
+     */
+    public static final JPEGQTable K1Luminance = new JPEGQTable(K1LumTable);
+    
+    /** 
+     * The K1Div2Luminance indicates K.1 table from JPEG
+     * specification with all elements divided by 2 and produces
+     * "very good" quality output. 
+     */
+    public static final JPEGQTable K1Div2Luminance = K1Luminance.getScaledInstance(0.5f, true);
+    
+    /** 
+     * The K2Chrominance indicates K.2 table from JPEG
+     * specification and produces "good" quality output. 
+     */
+    public static final JPEGQTable K2Chrominance = new JPEGQTable(K2ChrTable);
+    
+    /** 
+     * The Constant K2Div2Chrominance indicates K.2 table from JPEG
+     * specification with all elements divided by 2 and produces
+     * "very good" quality output. 
+     */
+    public static final JPEGQTable K2Div2Chrominance = K2Chrominance.getScaledInstance(0.5f, true);;
+
+
+    /**
+     * Instantiates a new JPEGQTable from the array, which 
+     * should contain 64 elements in natural order.
+     * 
+     * @param table the quantization table.
+     */
+    public JPEGQTable(int[] table) {
+        if (table == null) {
+            throw new IllegalArgumentException("table should not be NULL");
+        }
+        if (table.length != SIZE) {
+            throw new IllegalArgumentException("illegal table size: " + table.length);
+        }
+        theTable = table.clone();
+    }
+
+    /**
+     * Gets the current quantization table as an array of int values.
+     * 
+     * @return the current quantization table as an array of int values.
+     */
+    public int[] getTable() {
+        return theTable.clone();
+    }
+
+    /**
+     * Gets the scaled instance as quantization table where 
+     * the values are multiplied by the scaleFactor and then clamped 
+     * if forceBaseline is true.
+     * 
+     * @param scaleFactor the scale factor of table.
+     * @param forceBaseline the force baseline flag, the values 
+     * should be clamped if true.
+     * 
+     * @return the new quantization table.
+     */
+    public JPEGQTable getScaledInstance(float scaleFactor, boolean forceBaseline) {
+        int table[] = new int[SIZE];
+
+        int maxValue = forceBaseline ? BASELINE_MAX : MAX;
+
+        for (int i = 0; i < theTable.length; i++) {
+            int rounded = Math.round(theTable[i] * scaleFactor);
+            if (rounded < 1) {
+                rounded = 1;
+            }
+            if (rounded > maxValue) {
+                rounded = maxValue;
+            }
+            table[i] = rounded;
+        }
+        return new JPEGQTable(table);
+    }
+
+    /**
+     * Returns the string representation of this JPEGQTable object.
+     * 
+     * @return the string representation of this JPEGQTable object.
+     */
+    @Override
+    public String toString() {
+        //-- TODO more informative info
+        return "JPEGQTable";
+    }
+}
diff --git a/awt/javax/imageio/spi/IIORegistry.java b/awt/javax/imageio/spi/IIORegistry.java
new file mode 100644
index 0000000..3c1c989
--- /dev/null
+++ b/awt/javax/imageio/spi/IIORegistry.java
@@ -0,0 +1,110 @@
+/*
+ *  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.spi;
+
+import java.util.Arrays;
+
+import org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReaderSpi;
+import org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriterSpi;
+import org.apache.harmony.x.imageio.plugins.png.PNGImageReaderSpi;
+import org.apache.harmony.x.imageio.plugins.png.PNGImageWriterSpi;
+import org.apache.harmony.x.imageio.spi.FileIISSpi;
+import org.apache.harmony.x.imageio.spi.FileIOSSpi;
+import org.apache.harmony.x.imageio.spi.InputStreamIISSpi;
+import org.apache.harmony.x.imageio.spi.OutputStreamIOSSpi;
+import org.apache.harmony.x.imageio.spi.RAFIISSpi;
+import org.apache.harmony.x.imageio.spi.RAFIOSSpi;
+
+/*
+ * @author Rustem V. Rafikov, Viskov Nikolay
+ * @version $Revision: 1.3 $
+ */
+
+/**
+ * The IIORegistry class registers service provider instances 
+ * (SPI). Service provider instances are recognized by specific 
+ * meta-information in the JAR files containing them. The JAR
+ * files with SPI classes are loaded from the application class 
+ * path. 
+ */
+public final class IIORegistry extends ServiceRegistry {
+
+    /** The instance. */
+    private static IIORegistry instance;
+
+    /** The Constant CATEGORIES. */
+    private static final Class[] CATEGORIES = new Class[] {
+        javax.imageio.spi.ImageWriterSpi.class,
+        javax.imageio.spi.ImageReaderSpi.class,
+        javax.imageio.spi.ImageInputStreamSpi.class,
+        //javax.imageio.spi.ImageTranscoderSpi.class,
+        javax.imageio.spi.ImageOutputStreamSpi.class
+    };
+
+    /**
+     * Instantiates a new iIO registry.
+     */
+    private IIORegistry() {
+        super(Arrays.<Class<?>>asList(CATEGORIES).iterator());
+        registerBuiltinSpis();
+        registerApplicationClasspathSpis();
+    }
+
+    /**
+     * Register builtin spis.
+     */
+    private void registerBuiltinSpis() {
+        registerServiceProvider(new JPEGImageWriterSpi());
+        registerServiceProvider(new JPEGImageReaderSpi());
+        registerServiceProvider(new PNGImageReaderSpi());
+        registerServiceProvider(new PNGImageWriterSpi());
+        registerServiceProvider(new FileIOSSpi());
+        registerServiceProvider(new FileIISSpi());
+        registerServiceProvider(new RAFIOSSpi());
+        registerServiceProvider(new RAFIISSpi());
+        registerServiceProvider(new OutputStreamIOSSpi());        
+        registerServiceProvider(new InputStreamIISSpi());
+        //-- TODO implement
+    }
+
+    /**
+     * Gets the default IIORegistry instance.
+     * 
+     * @return the default IIORegistry instance.
+     */
+    public static IIORegistry getDefaultInstance() {
+        // TODO implement own instance for each ThreadGroup (see also ThreadLocal)
+        synchronized (IIORegistry.class) {
+            if (instance == null) {
+                instance = new IIORegistry();
+            }
+            return instance;
+        }
+    }
+
+    /**
+     * Registers all service providers from the application class 
+     * path.
+     */
+    public void registerApplicationClasspathSpis() {
+        //-- TODO implement for non-builtin plugins
+    }
+}
diff --git a/awt/javax/imageio/spi/IIOServiceProvider.java b/awt/javax/imageio/spi/IIOServiceProvider.java
new file mode 100644
index 0000000..f5873bf
--- /dev/null
+++ b/awt/javax/imageio/spi/IIOServiceProvider.java
@@ -0,0 +1,97 @@
+/*
+ *  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.spi;
+
+import java.util.Locale;
+
+/**
+ * The IIOServiceProvider abstract class provides base functionality 
+ * for imageio service provider interfaces (SPIs). 
+ */
+public abstract class IIOServiceProvider implements RegisterableService {
+
+    /** The vendor name of this service provider. */
+    protected String vendorName;
+    
+    /** The version of this service provider. */
+    protected String version;
+
+    /**
+     * Instantiates a new IIOServiceProvider.
+     * 
+     * @param vendorName the vendor name of service provider.
+     * @param version the version of service provider.
+     */
+    public IIOServiceProvider(String vendorName, String version) {
+        if (vendorName == null) {
+            throw new NullPointerException("vendor name cannot be NULL");
+        }
+        if (version == null) {
+            throw new NullPointerException("version name cannot be NULL");
+        }
+        this.vendorName = vendorName;
+        this.version = version;
+    }
+
+    /**
+     * Instantiates a new IIOServiceProvider.
+     */
+    public IIOServiceProvider() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    public void onRegistration(ServiceRegistry registry, Class<?> category) {
+        // the default impl. does nothing
+    }
+
+    public void onDeregistration(ServiceRegistry registry, Class<?> category) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets the vendor name of this service provider.
+     * 
+     * @return the vendor name of this service provider.
+     */
+    public String getVendorName() {
+        return vendorName;
+    }
+
+    /**
+     * Gets the version of this service provider.
+     * 
+     * @return the version of this service provider.
+     */
+    public String getVersion() {
+        return version;
+    }
+
+    /**
+     * Gets a description of this service provider.   
+     * The result string should be localized for the specified 
+     * Locale.
+     * 
+     * @param locale the specified Locale.
+     * 
+     * @return the description of this service provider.
+     */
+    public abstract String getDescription(Locale locale);
+}
diff --git a/awt/javax/imageio/spi/ImageInputStreamSpi.java b/awt/javax/imageio/spi/ImageInputStreamSpi.java
new file mode 100644
index 0000000..47d210a
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageInputStreamSpi.java
@@ -0,0 +1,126 @@
+/*
+ *  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.spi;
+
+import java.io.File;
+import java.io.IOException;
+import javax.imageio.stream.ImageInputStream;
+
+/**
+ * The ImageInputStreamSpi abstract class is a service provider 
+ * interface (SPI) for ImageInputStreams.  
+ */
+public abstract class ImageInputStreamSpi extends IIOServiceProvider implements
+        RegisterableService {
+    
+    /** The input class. */
+    protected Class<?> inputClass;
+
+    /**
+     * Instantiates a new ImageInputStreamSpi.
+     */
+    protected ImageInputStreamSpi() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Instantiates a new ImageInputStreamSpi.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     * @param inputClass the input class.
+     */
+    public ImageInputStreamSpi(String vendorName, String version, Class<?> inputClass) {
+        super(vendorName, version);
+        this.inputClass = inputClass;
+    }
+
+    /**
+     * Gets an input Class object that represents class or 
+     * interface that must be implemented by an input source.
+     * 
+     * @return the input class.
+     */
+    public Class<?> getInputClass() {
+        return inputClass;
+    }
+
+    /**
+     * Returns true if the ImageInputStream can use a cache 
+     * file. If this method returns false, the value of the 
+     * useCache parameter of createInputStreamInstance will 
+     * be ignored. The default implementation returns false.
+     * 
+     * @return true if the ImageInputStream can use a cache 
+     * file, false otherwise.
+     */
+    public boolean canUseCacheFile() {
+        return false; //-- def
+    }
+
+    /**
+     * Returns true if the ImageInputStream implementation 
+     * requires the use of a cache file. The default implementation 
+     * returns false.
+     * 
+     * @return true if the ImageInputStream implementation 
+     * requires the use of a cache file, false otherwise.
+     */
+    public boolean needsCacheFile() {
+        return false; // def
+    }
+
+    /**
+     * Creates the ImageInputStream associated with this 
+     * service provider. The input object should
+     * be an instance of the class returned by th getInputClass 
+     * method. This method uses the specified directory
+     * for the cache file if the useCache parameter is true. 
+     * 
+     * @param input the input Object.
+     * @param useCache the flag indicating if a cache file 
+     * is needed or not.
+     * @param cacheDir the cache directory.
+     * 
+     * @return the ImageInputStream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract ImageInputStream createInputStreamInstance(Object input, boolean useCache,
+            File cacheDir) throws IOException;
+
+    /**
+     * Creates the ImageInputStream associated with this 
+     * service provider. The input object should
+     * be an instance of the class returned by getInputClass 
+     * method. This method uses the default system directory
+     * for the cache file, if it is needed. 
+     * 
+     * @param input the input Object.
+     * 
+     * @return the ImageInputStream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public ImageInputStream createInputStreamInstance(Object input) throws IOException {
+        return createInputStreamInstance(input, true, null);
+    }
+}
diff --git a/awt/javax/imageio/spi/ImageOutputStreamSpi.java b/awt/javax/imageio/spi/ImageOutputStreamSpi.java
new file mode 100644
index 0000000..d45e24c
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageOutputStreamSpi.java
@@ -0,0 +1,126 @@
+/*
+ *  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.spi;
+
+import javax.imageio.stream.ImageOutputStream;
+import java.io.IOException;
+import java.io.File;
+
+/**
+ * The ImageOutputStreamSpi abstract class is a service provider 
+ * interface (SPI) for ImageOutputStreams. 
+ */
+public abstract class ImageOutputStreamSpi extends IIOServiceProvider implements
+        RegisterableService {
+    
+    /** The output class. */
+    protected Class<?> outputClass;
+
+    /**
+     * Instantiates a new ImageOutputStreamSpi.
+     */
+    protected ImageOutputStreamSpi() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Instantiates a new ImageOutputStreamSpi.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     * @param outputClass the output class.
+     */
+    public ImageOutputStreamSpi(String vendorName, String version, Class<?> outputClass) {
+        super(vendorName, version);
+        this.outputClass = outputClass;
+    }
+
+    /**
+     * Gets an output Class object that represents the class or 
+     * interface that must be implemented by an output source.
+     * 
+     * @return the output class.
+     */
+    public Class<?> getOutputClass() {
+        return outputClass;
+    }
+
+    /**
+     * Returns true if the ImageOutputStream can use a cache 
+     * file. If this method returns false, the value of the 
+     * useCache parameter of createOutputStreamInstance will 
+     * be ignored. The default implementation returns false.
+     * 
+     * @return true if the ImageOutputStream can use a cache 
+     * file, false otherwise.
+     */
+    public boolean canUseCacheFile() {
+        return false; // def
+    }
+
+    /**
+     * Returns true if the ImageOutputStream  implementation 
+     * requires the use of a cache file. The default implementation 
+     * returns false.
+     * 
+     * @return true if the ImageOutputStream  implementation 
+     * requires the use of a cache file, false otherwise.
+     */
+    public boolean needsCacheFile() {
+        return false; // def
+    }
+
+    /**
+     * Creates the ImageOutputStream associated with this 
+     * service provider. The output object should
+     * be an instance of the class returned by getOutputClass 
+     * method. This method uses the default system directory
+     * for the cache file, if it is needed. 
+     * 
+     * @param output the output Object.
+     * 
+     * @return the ImageOutputStream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public ImageOutputStream createOutputStreamInstance(Object output) throws IOException {
+        return createOutputStreamInstance(output, true, null);
+    }
+
+    /**
+     * Creates the ImageOutputStream associated with this 
+     * service provider. The output object should
+     * be an instance of the class returned by getInputClass 
+     * method. This method uses the specified directory
+     * for the cache file, if the useCache parameter is true. 
+     * 
+     * @param output the output Object.
+     * @param useCache the flag indicating if cache file 
+     * is needed or not.
+     * @param cacheDir the cache directory.
+     * 
+     * @return the ImageOutputStream.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract ImageOutputStream createOutputStreamInstance(Object output,
+            boolean useCache, File cacheDir) throws IOException;
+}
diff --git a/awt/javax/imageio/spi/ImageReaderSpi.java b/awt/javax/imageio/spi/ImageReaderSpi.java
new file mode 100644
index 0000000..2e2484c
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageReaderSpi.java
@@ -0,0 +1,186 @@
+/*
+ *  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.spi;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.ImageReader;
+import java.io.IOException;
+
+/**
+ * The ImageReaderSpi abstract class is a service provider 
+ * interface (SPI) for ImageReaders.
+ */
+public abstract class ImageReaderSpi extends ImageReaderWriterSpi {
+
+    /** 
+     * The STANDARD_INPUT_TYPE contains ImageInputStream.class. 
+     */
+    public static final Class[] STANDARD_INPUT_TYPE = new Class[] {ImageInputStream.class};
+
+    /** The input types. */
+    protected Class[] inputTypes;
+    
+    /** The writer SPI names. */
+    protected String[] writerSpiNames;
+
+    /**
+     * Instantiates a new ImageReaderSpi.
+     */
+    protected ImageReaderSpi() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Instantiates a new ImageReaderSpi.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     * @param names the format names.
+     * @param suffixes the array of strings representing the file suffixes. 
+     * @param MIMETypes the an array of strings representing MIME types.
+     * @param pluginClassName the plugin class name.
+     * @param inputTypes the input types.
+     * @param writerSpiNames the array of strings with class names of all 
+     * associated ImageWriters.
+     * @param supportsStandardStreamMetadataFormat the value indicating
+     * if stream metadata can be described by standart metadata format.
+     * @param nativeStreamMetadataFormatName the native stream metadata 
+     * format name, returned by getNativeStreamMetadataFormatName.
+     * @param nativeStreamMetadataFormatClassName the native stream 
+     * metadata format class name, returned by getNativeStreamMetadataFormat.
+     * @param extraStreamMetadataFormatNames the extra stream metadata 
+     * format names, returned by getExtraStreamMetadataFormatNames.
+     * @param extraStreamMetadataFormatClassNames the extra stream metadata 
+     * format class names, returned by getStreamMetadataFormat.
+     * @param supportsStandardImageMetadataFormat the value indicating
+     * if image metadata can be described by standart metadata format.
+     * @param nativeImageMetadataFormatName the native image metadata 
+     * format name, returned by getNativeImageMetadataFormatName.
+     * @param nativeImageMetadataFormatClassName the native image
+     * metadata format class name, returned by getNativeImageMetadataFormat.
+     * @param extraImageMetadataFormatNames the extra image metadata 
+     * format names, returned by getExtraImageMetadataFormatNames.
+     * @param extraImageMetadataFormatClassNames the extra image metadata 
+     * format class names, returned by getImageMetadataFormat.
+     */
+    public ImageReaderSpi(String vendorName, String version, String[] names, String[] suffixes,
+                             String[] MIMETypes, String pluginClassName,
+                             Class[] inputTypes, String[] writerSpiNames,
+                             boolean supportsStandardStreamMetadataFormat,
+                             String nativeStreamMetadataFormatName,
+                             String nativeStreamMetadataFormatClassName,
+                             String[] extraStreamMetadataFormatNames,
+                             String[] extraStreamMetadataFormatClassNames,
+                             boolean supportsStandardImageMetadataFormat,
+                             String nativeImageMetadataFormatName,
+                             String nativeImageMetadataFormatClassName,
+                             String[] extraImageMetadataFormatNames,
+                             String[] extraImageMetadataFormatClassNames) {
+        super(vendorName, version, names, suffixes, MIMETypes, pluginClassName,
+                supportsStandardStreamMetadataFormat, nativeStreamMetadataFormatName,
+                nativeStreamMetadataFormatClassName, extraStreamMetadataFormatNames,
+                extraStreamMetadataFormatClassNames, supportsStandardImageMetadataFormat,
+                nativeImageMetadataFormatName, nativeImageMetadataFormatClassName,
+                extraImageMetadataFormatNames, extraImageMetadataFormatClassNames);
+
+        if (inputTypes == null || inputTypes.length == 0) {
+            throw new NullPointerException("input types array cannot be NULL or empty");
+        }
+        this.inputTypes = inputTypes;
+        this.writerSpiNames = writerSpiNames;
+    }
+
+    /**
+     * Gets an array of Class objects whose types can be used 
+     * as input for this reader.
+     * 
+     * @return the input types.
+     */
+    public Class[] getInputTypes() {
+        return inputTypes;
+    }
+
+    /**
+     * Returns true if the format of source object is
+     * supported by this reader.
+     * 
+     * @param source the source object to be decoded 
+     * (for example an ImageInputStream).
+     * 
+     * @return true if the format of source object is
+     * supported by this reader, false otherwise.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract boolean canDecodeInput(Object source) throws IOException;
+
+    /**
+     * Returns an instance of the ImageReader implementation for
+     * this service provider.
+     * 
+     * @return the ImageReader.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public ImageReader createReaderInstance() throws IOException {
+        return createReaderInstance(null);
+    }
+
+    /**
+     * Returns an instance of the ImageReader implementation for
+     * this service provider.
+     * 
+     * @param extension the a plugin specific extension object, or null.
+     * 
+     * @return the ImageReader.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract ImageReader createReaderInstance(Object extension) throws IOException;
+
+    /**
+     * Checks whether or not the specified ImageReader object 
+     * is an instance of the ImageReader associated with this 
+     * service provider or not.
+     * 
+     * @param reader the ImageReader.
+     * 
+     * @return true, if the specified ImageReader object 
+     * is an instance of the ImageReader associated with this 
+     * service provider, false otherwise.
+     */
+    public boolean isOwnReader(ImageReader reader) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an array of strings with names of the ImageWriterSpi 
+     * classes that support the internal metadata representation 
+     * used by the ImageReader of this service provider, or null if 
+     * there are no such ImageWriters.
+     * 
+     * @return an array of strings with names of the ImageWriterSpi 
+     * classes.
+     */
+    public String[] getImageWriterSpiNames() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+}
diff --git a/awt/javax/imageio/spi/ImageReaderWriterSpi.java b/awt/javax/imageio/spi/ImageReaderWriterSpi.java
new file mode 100644
index 0000000..b3c0f92
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageReaderWriterSpi.java
@@ -0,0 +1,315 @@
+/*
+ *  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.spi;
+
+import org.apache.harmony.x.imageio.metadata.IIOMetadataUtils;
+
+import javax.imageio.metadata.IIOMetadataFormat;
+
+/**
+ * The ImageReaderWriterSpi class is a superclass for the 
+ * ImageReaderSpi and ImageWriterSpi SPIs.
+ */
+public abstract class ImageReaderWriterSpi extends IIOServiceProvider
+        implements RegisterableService {
+
+    /** The names. */
+    protected String[] names;
+    
+    /** The suffixes. */
+    protected String[] suffixes;
+    
+    /** The MIME types. */
+    protected String[] MIMETypes;
+    
+    /** The plugin class name. */
+    protected String pluginClassName;
+    
+    /** Whether the reader/writer supports standard stream metadata format. */
+    protected boolean supportsStandardStreamMetadataFormat;
+    
+    /** The native stream metadata format name. */
+    protected String nativeStreamMetadataFormatName;
+    
+    /** The native stream metadata format class name. */
+    protected String nativeStreamMetadataFormatClassName;
+    
+    /** The extra stream metadata format names. */
+    protected String[] extraStreamMetadataFormatNames;
+    
+    /** The extra stream metadata format class names. */
+    protected String[] extraStreamMetadataFormatClassNames;
+    
+    /** Whether the reader/writer supports standard image metadata format. */
+    protected boolean supportsStandardImageMetadataFormat;
+    
+    /** The native image metadata format name. */
+    protected String nativeImageMetadataFormatName;
+    
+    /** The native image metadata format class name. */
+    protected String nativeImageMetadataFormatClassName;
+    
+    /** The extra image metadata format names. */
+    protected String[] extraImageMetadataFormatNames;
+    
+    /** The extra image metadata format class names. */
+    protected String[] extraImageMetadataFormatClassNames;
+
+    /**
+     * Instantiates a new ImageReaderWriterSpi.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     * @param names the format names.
+     * @param suffixes the array of strings representing the file suffixes. 
+     * @param MIMETypes the an array of strings representing MIME types.
+     * @param pluginClassName the plugin class name.
+     * @param supportsStandardStreamMetadataFormat the value indicating
+     * if stream metadata can be described by standart metadata format.
+     * @param nativeStreamMetadataFormatName the native stream metadata 
+     * format name, returned by getNativeStreamMetadataFormatName.
+     * @param nativeStreamMetadataFormatClassName the native stream 
+     * metadata format class name, returned by getNativeStreamMetadataFormat.
+     * @param extraStreamMetadataFormatNames the extra stream metadata 
+     * format names, returned by getExtraStreamMetadataFormatNames.
+     * @param extraStreamMetadataFormatClassNames the extra stream metadata 
+     * format class names, returned by getStreamMetadataFormat.
+     * @param supportsStandardImageMetadataFormat the value indicating
+     * if image metadata can be described by standard metadata format.
+     * @param nativeImageMetadataFormatName the native image metadata 
+     * format name, returned by getNativeImageMetadataFormatName.
+     * @param nativeImageMetadataFormatClassName the native image
+     * metadata format class name, returned by getNativeImageMetadataFormat.
+     * @param extraImageMetadataFormatNames the extra image metadata 
+     * format names, returned by getExtraImageMetadataFormatNames.
+     * @param extraImageMetadataFormatClassNames the extra image metadata 
+     * format class names, returned by getImageMetadataFormat.
+     */
+    public ImageReaderWriterSpi(String vendorName, String version, String[] names,
+                                String[] suffixes, String[] MIMETypes,
+                                String pluginClassName,
+                                boolean supportsStandardStreamMetadataFormat,
+                                String nativeStreamMetadataFormatName,
+                                String nativeStreamMetadataFormatClassName,
+                                String[] extraStreamMetadataFormatNames,
+                                String[] extraStreamMetadataFormatClassNames,
+                                boolean supportsStandardImageMetadataFormat,
+                                String nativeImageMetadataFormatName,
+                                String nativeImageMetadataFormatClassName,
+                                String[] extraImageMetadataFormatNames,
+                                String[] extraImageMetadataFormatClassNames) {
+        super(vendorName, version);
+
+        if (names == null || names.length == 0) {
+            throw new NullPointerException("format names array cannot be NULL or empty");
+        }
+
+        if (pluginClassName == null) {
+            throw new NullPointerException("Plugin class name cannot be NULL");
+        }
+
+        // We clone all the arrays to be consistent with the fact that
+        // some methods of this class must return clones of the arrays
+        // as it is stated in the spec.
+        this.names = names.clone();
+        this.suffixes = suffixes == null ? null : suffixes.clone();
+        this.MIMETypes = MIMETypes == null ? null : MIMETypes.clone();
+        this.pluginClassName = pluginClassName;
+        this.supportsStandardStreamMetadataFormat = supportsStandardStreamMetadataFormat;
+        this.nativeStreamMetadataFormatName = nativeStreamMetadataFormatName;
+        this.nativeStreamMetadataFormatClassName = nativeStreamMetadataFormatClassName;
+
+        this.extraStreamMetadataFormatNames =
+                extraStreamMetadataFormatNames == null ?
+                null : extraStreamMetadataFormatNames.clone();
+
+        this.extraStreamMetadataFormatClassNames =
+                extraStreamMetadataFormatClassNames == null ?
+                null : extraStreamMetadataFormatClassNames.clone();
+
+        this.supportsStandardImageMetadataFormat = supportsStandardImageMetadataFormat;
+        this.nativeImageMetadataFormatName = nativeImageMetadataFormatName;
+        this.nativeImageMetadataFormatClassName = nativeImageMetadataFormatClassName;
+
+        this.extraImageMetadataFormatNames =
+                extraImageMetadataFormatNames == null ?
+                null : extraImageMetadataFormatNames.clone();
+
+        this.extraImageMetadataFormatClassNames =
+                extraImageMetadataFormatClassNames == null ?
+                null : extraImageMetadataFormatClassNames.clone();
+    }
+
+    /**
+     * Instantiates a new ImageReaderWriterSpi.
+     */
+    public ImageReaderWriterSpi() {}
+
+    /**
+     * Gets an array of strings representing names of the formats 
+     * that can be used by the ImageReader 
+     * or ImageWriter implementation associated with this service 
+     * provider. 
+     * 
+     * @return an array of supported format names.
+     */
+    public String[] getFormatNames() {
+        return names.clone();
+    }
+
+    /**
+     * Gets an array of strings representing file suffixes 
+     * associated with the formats that can be used by the 
+     * ImageReader or ImageWriter implementation of this
+     * service provider.
+     * 
+     * @return an array of file suffixes.
+     */
+    public String[] getFileSuffixes() {
+        return suffixes == null ? null : suffixes.clone();
+    }
+
+    /**
+     * Gets an array of strings with the names of 
+     * additional formats of the image metadata objects 
+     * produced or consumed by this plug-in.
+     * 
+     * @return the array of extra image metadata format names.
+     */
+    public String[] getExtraImageMetadataFormatNames() {
+        return extraImageMetadataFormatNames == null ? null : extraImageMetadataFormatNames.clone();
+    }
+
+    /**
+     * Gets an array of strings with the names of 
+     * additional formats of the stream metadata objects 
+     * produced or consumed by this plug-in.
+     * 
+     * @return the array of extra stream metadata format names.
+     */
+    public String[] getExtraStreamMetadataFormatNames() {
+        return extraStreamMetadataFormatNames == null ? null : extraStreamMetadataFormatNames.clone();
+    }
+
+    /**
+     * Gets an IIOMetadataFormat object for the specified image 
+     * metadata format name. 
+     * 
+     * @param formatName the format name.
+     * 
+     * @return the IIOMetadataFormat, or null.
+     */
+    public IIOMetadataFormat getImageMetadataFormat(String formatName) {
+        return IIOMetadataUtils.instantiateMetadataFormat(
+                formatName, supportsStandardImageMetadataFormat,
+                nativeImageMetadataFormatName, nativeImageMetadataFormatClassName,
+                extraImageMetadataFormatNames, extraImageMetadataFormatClassNames
+        );
+    }
+
+    /**
+     * Gets an IIOMetadataFormat object for the specified stream 
+     * metadata format name. 
+     * 
+     * @param formatName the format name.
+     * 
+     * @return the IIOMetadataFormat, or null.
+     */
+    public IIOMetadataFormat getStreamMetadataFormat(String formatName) {
+        return IIOMetadataUtils.instantiateMetadataFormat(
+                formatName, supportsStandardStreamMetadataFormat,
+                nativeStreamMetadataFormatName, nativeStreamMetadataFormatClassName,
+                extraStreamMetadataFormatNames, extraStreamMetadataFormatClassNames
+        );
+    }
+
+    /**
+     * Gets an array of strings representing the MIME types 
+     * of the formats that are supported by the 
+     * ImageReader or ImageWriter implementation of this 
+     * service provider.
+     * 
+     * @return the array MIME types.
+     */
+    public String[] getMIMETypes() {
+        return MIMETypes == null ? null : MIMETypes.clone();
+    }
+
+    /**
+     * Gets the name of the native image metadata format for 
+     * this reader/writer, which allows for lossless encoding
+     * or decoding of the image metadata with the format.
+     * 
+     * @return the string with native image metadata format name, 
+     * or null.
+     */
+    public String getNativeImageMetadataFormatName() {
+        return nativeImageMetadataFormatName;
+    }
+
+    /**
+     * Gets the name of the native stream metadata format for 
+     * this reader/writer, which allows for lossless encoding
+     * or decoding of the stream metadata with the format.
+     * 
+     * @return the string with native stream metadata format name, 
+     * or null.
+     */
+    public String getNativeStreamMetadataFormatName() {
+        return nativeStreamMetadataFormatName;
+    }
+
+    /**
+     * Gets the class name of the ImageReader 
+     * or ImageWriter associated with this service provider.
+     * 
+     * @return the class name.
+     */
+    public String getPluginClassName() {
+        return pluginClassName;
+    }
+
+    /**
+     * Checks if the standard metadata format is supported 
+     * by the getAsTree and setFromTree methods for the 
+     * image metadata objects produced or consumed by this 
+     * reader or writer.
+     * 
+     * @return true, if standard image metadata format is 
+     * supported, false otherwise.
+     */
+    public boolean isStandardImageMetadataFormatSupported() {
+        return supportsStandardImageMetadataFormat;
+    }
+
+    /**
+     * Checks if the standard metadata format is supported 
+     * by the getAsTree and setFromTree methods for the 
+     * stream metadata objects produced or consumed by this 
+     * reader or writer.
+     * 
+     * @return true, if standard stream metadata format is 
+     * supported, false otherwise.
+     */
+    public boolean isStandardStreamMetadataFormatSupported() {
+        return supportsStandardStreamMetadataFormat;
+    }
+}
diff --git a/awt/javax/imageio/spi/ImageTranscoderSpi.java b/awt/javax/imageio/spi/ImageTranscoderSpi.java
new file mode 100644
index 0000000..68c4024
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageTranscoderSpi.java
@@ -0,0 +1,74 @@
+/*
+ *  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.spi;
+
+import javax.imageio.ImageTranscoder;
+
+/**
+ * The ImageTranscoderSpi class is a service provider interface (SPI) 
+ * for ImageTranscoders.
+ */
+public abstract class ImageTranscoderSpi extends IIOServiceProvider
+        implements RegisterableService {
+
+    /**
+     * Instantiates a new ImageTranscoderSpi.
+     */
+    protected ImageTranscoderSpi() {
+    }
+
+    /**
+     * Instantiates a new ImageTranscoderSpi with the specified
+     * vendor name and version.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     */
+    public ImageTranscoderSpi(String vendorName, String version) {
+        super(vendorName, version);
+    }
+
+    /**
+     * Gets the class name of an ImageReaderSpi that 
+     * produces IIOMetadata objects that can be used as 
+     * input to this transcoder.
+     * 
+     * @return the class name of an ImageReaderSpi.
+     */
+    public abstract String getReaderServiceProviderName();
+
+    /**
+     * Gets the class name of an ImageWriterSpi that 
+     * produces IIOMetadata objects that can be used as 
+     * input to this transcoder.
+     * 
+     * @return the class name of an ImageWriterSpi.
+     */
+    public abstract String getWriterServiceProviderName();
+
+    /**
+     * Creates an instance of the ImageTranscoder associated 
+     * with this service provider.
+     * 
+     * @return the ImageTranscoder instance.
+     */
+    public abstract ImageTranscoder createTranscoderInstance();
+}
diff --git a/awt/javax/imageio/spi/ImageWriterSpi.java b/awt/javax/imageio/spi/ImageWriterSpi.java
new file mode 100644
index 0000000..979ef77
--- /dev/null
+++ b/awt/javax/imageio/spi/ImageWriterSpi.java
@@ -0,0 +1,209 @@
+/*
+ *  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.spi;
+
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriter;
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+
+/**
+ * The ImageWriterSpi abstract class is a service provider 
+ * interface (SPI) for ImageWriters.
+ */
+public abstract class ImageWriterSpi extends ImageReaderWriterSpi {
+
+    /** The STANDARD_OUTPUT_TYPE contains ImageInputStream.class. */
+    public static final Class[] STANDARD_OUTPUT_TYPE = new Class[] {ImageInputStream.class};
+
+    /** The output types. */
+    protected Class[] outputTypes;
+    
+    /** The reader spi names. */
+    protected String[] readerSpiNames;
+
+    /**
+     * Instantiates a new ImageWriterSpi.
+     */
+    protected ImageWriterSpi() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Instantiates a new ImageWriterSpi with the specified parameters.
+     * 
+     * @param vendorName the vendor name.
+     * @param version the version.
+     * @param names the format names.
+     * @param suffixes the array of strings representing the file suffixes. 
+     * @param MIMETypes the an array of strings representing MIME types.
+     * @param pluginClassName the plugin class name.
+     * @param outputTypes the output types.
+     * @param readerSpiNames the array of strings with class names of all 
+     * associated ImageReaders.
+     * @param supportsStandardStreamMetadataFormat the value indicating
+     * if stream metadata can be described by standard metadata format.
+     * @param nativeStreamMetadataFormatName the native stream metadata 
+     * format name, returned by getNativeStreamMetadataFormatName.
+     * @param nativeStreamMetadataFormatClassName the native stream 
+     * metadata format class name, returned by getNativeStreamMetadataFormat.
+     * @param extraStreamMetadataFormatNames the extra stream metadata 
+     * format names, returned by getExtraStreamMetadataFormatNames.
+     * @param extraStreamMetadataFormatClassNames the extra stream metadata 
+     * format class names, returned by getStreamMetadataFormat.
+     * @param supportsStandardImageMetadataFormat the value indicating
+     * if image metadata can be described by standard metadata format.
+     * @param nativeImageMetadataFormatName the native image metadata 
+     * format name, returned by getNativeImageMetadataFormatName.
+     * @param nativeImageMetadataFormatClassName the native image
+     * metadata format class name, returned by getNativeImageMetadataFormat.
+     * @param extraImageMetadataFormatNames the extra image metadata 
+     * format names, returned by getExtraImageMetadataFormatNames.
+     * @param extraImageMetadataFormatClassNames the extra image metadata 
+     * format class names, returned by getImageMetadataFormat.
+     */
+    public ImageWriterSpi(String vendorName, String version, String[] names,
+                             String[] suffixes, String[] MIMETypes,
+                             String pluginClassName,
+                             Class[] outputTypes, String[] readerSpiNames,
+                             boolean supportsStandardStreamMetadataFormat,
+                             String nativeStreamMetadataFormatName,
+                             String nativeStreamMetadataFormatClassName,
+                             String[] extraStreamMetadataFormatNames,
+                             String[] extraStreamMetadataFormatClassNames,
+                             boolean supportsStandardImageMetadataFormat,
+                             String nativeImageMetadataFormatName,
+                             String nativeImageMetadataFormatClassName,
+                             String[] extraImageMetadataFormatNames,
+                             String[] extraImageMetadataFormatClassNames) {
+        super(vendorName, version, names, suffixes, MIMETypes, pluginClassName,
+                supportsStandardStreamMetadataFormat, nativeStreamMetadataFormatName,
+                nativeStreamMetadataFormatClassName, extraStreamMetadataFormatNames,
+                extraStreamMetadataFormatClassNames, supportsStandardImageMetadataFormat,
+                nativeImageMetadataFormatName, nativeImageMetadataFormatClassName,
+                extraImageMetadataFormatNames, extraImageMetadataFormatClassNames);
+
+        if (outputTypes == null || outputTypes.length == 0) {
+            throw new NullPointerException("output types array cannot be NULL or empty");
+        }
+
+        this.outputTypes = outputTypes;
+        this.readerSpiNames = readerSpiNames;
+    }
+
+    /**
+     * Returns true if the format of the writer's output is lossless. 
+     * The default implementation returns true.
+     * 
+     * @return true, if a format is lossless, false otherwise.
+     */
+    public boolean isFormatLossless() {
+        return true;
+    }
+
+    /**
+     * Gets an array of Class objects whose types 
+     * can be used as output for this writer.
+     * 
+     * @return the output types.
+     */
+    public Class[] getOutputTypes() {
+        return outputTypes;
+    }
+
+    /**
+     * Checks whether or not the ImageWriter implementation associated 
+     * with this service provider can encode an image with 
+     * the specified type.
+     * 
+     * @param type the ImageTypeSpecifier.
+     * 
+     * @return true, if an image with the specified type can be
+     * encoded, false otherwise. 
+     */
+    public abstract boolean canEncodeImage(ImageTypeSpecifier type);
+
+    /**
+     * Checks whether or not the ImageWriter implementation associated 
+     * with this service provider can encode the specified RenderedImage.
+     * 
+     * @param im the RenderedImage.
+     * 
+     * @return true, if RenderedImage can be encoded, 
+     * false otherwise. 
+     */
+    public boolean canEncodeImage(RenderedImage im) {
+        return canEncodeImage(ImageTypeSpecifier.createFromRenderedImage(im));
+    }
+
+    /**
+     * Returns an instance of the ImageWriter implementation for
+     * this service provider.
+     * 
+     * @return the ImageWriter.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public ImageWriter createWriterInstance() throws IOException {
+        return createWriterInstance(null);
+    }
+
+    /**
+     * Returns an instance of the ImageWriter implementation for
+     * this service provider.
+     * 
+     * @param extension the a plugin specific extension object, or null.
+     * 
+     * @return the ImageWriter.
+     * 
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    public abstract ImageWriter createWriterInstance(Object extension) throws IOException;
+
+    /**
+     * Checks whether or not the specified ImageWriter object 
+     * is an instance of the ImageWriter associated with this 
+     * service provider or not.
+     * 
+     * @param writer the ImageWriter.
+     * 
+     * @return true, if the specified ImageWriter object 
+     * is an instance of the ImageWriter associated with this 
+     * service provider, false otherwise.
+     */
+    public boolean isOwnWriter(ImageWriter writer) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an array of strings with names of the ImageReaderSpi 
+     * classes that support the internal metadata representation 
+     * used by the ImageWriter of this service provider, or null if 
+     * there are no such ImageReaders.
+     * 
+     * @return an array of strings with names of the ImageWriterSpi 
+     * classes.
+     */
+    public String[] getImageReaderSpiNames() {
+        return readerSpiNames;
+    }
+}
diff --git a/awt/javax/imageio/spi/RegisterableService.java b/awt/javax/imageio/spi/RegisterableService.java
new file mode 100644
index 0000000..b50754e
--- /dev/null
+++ b/awt/javax/imageio/spi/RegisterableService.java
@@ -0,0 +1,50 @@
+/*
+ *  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.spi;
+
+/**
+ * The RegisterableService interface provides service provider 
+ * objects that can be registered by a ServiceRegistry, and 
+ * notifications that registration and deregistration have been
+ * performed.
+ */
+public interface RegisterableService {
+    
+    /**
+     * This method is called when the object which implements this
+     * interface is registered to the specified category of the 
+     * specified registry.
+     * 
+     * @param registry the ServiceRegistry to be registered.
+     * @param category the class representing a category.
+     */
+    void onRegistration(ServiceRegistry registry, Class<?> category);
+    
+    /**
+     * This method is called when the object which implements this
+     * interface is deregistered to the specified category of the 
+     * specified registry.
+     * 
+     * @param registry the ServiceRegistry to be registered.
+     * @param category the class representing a category.
+     */
+    void onDeregistration(ServiceRegistry registry, Class<?> category);
+}
diff --git a/awt/javax/imageio/spi/ServiceRegistry.java b/awt/javax/imageio/spi/ServiceRegistry.java
new file mode 100644
index 0000000..1a18b02
--- /dev/null
+++ b/awt/javax/imageio/spi/ServiceRegistry.java
@@ -0,0 +1,516 @@
+/*
+ *  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.spi;
+
+import java.util.*;
+import java.util.Map.Entry;
+
+/**
+ * The ServiceRegistry class provides ability to register, 
+ * deregister, look up and obtain service provider instances (SPIs).
+ * A service means a set of interfaces and classes, and a service 
+ * provider is an implementation of a service. Service providers can 
+ * be associated with one or more categories. Each category is defined 
+ * by a class or interface. Only a single instance of a each class is 
+ * allowed to be registered as a category. 
+ */
+public class ServiceRegistry {
+
+    /** The categories. */
+    CategoriesMap categories = new CategoriesMap(this);
+
+    /**
+     * Instantiates a new ServiceRegistry with the specified categories.
+     * 
+     * @param categoriesIterator an Iterator of Class objects 
+     * for defining of categories.
+     */
+    public ServiceRegistry(Iterator<Class<?>> categoriesIterator) {
+        if (null == categoriesIterator) {
+            throw new IllegalArgumentException("categories iterator should not be NULL");
+        }
+        while(categoriesIterator.hasNext()) {
+            Class<?> c =  categoriesIterator.next();
+            categories.addCategory(c);
+        }
+    }
+
+    /**
+     * Looks up and instantiates the available providers of this service using 
+     * the specified class loader.
+     * 
+     * @param providerClass the Class object of the provider to be looked up.
+     * @param loader the class loader to be used.
+     * 
+     * @return the iterator of providers objects for this service.
+     */
+    public static <T> Iterator<T> lookupProviders(Class<T> providerClass, ClassLoader loader) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Looks up and instantiates the available providers of this service using 
+     * the context class loader.
+     * 
+     * @param providerClass the Class object of the provider to be looked up.
+     * 
+     * @return the iterator of providers objects for this service.
+     */
+    public static <T> Iterator<T> lookupProviders(Class<T> providerClass) {
+        return lookupProviders(providerClass, Thread.currentThread().getContextClassLoader());
+    }
+
+    /**
+     * Registers the specified service provider object in the
+     * specified categories.
+     * 
+     * @param provider the specified provider to be registered.
+     * @param category the category.
+     * 
+     * @return true if no provider of the same class is registered 
+     * in this category, false otherwise.
+     */
+    public <T> boolean registerServiceProvider(T provider, Class<T> category) {
+        return categories.addProvider(provider, category);
+    }
+
+    /**
+     * Registers a list of service providers.
+     * 
+     * @param providers the list of service providers.
+     */
+    public void registerServiceProviders(Iterator<?> providers) {
+        for (Iterator<?> iterator = providers; iterator.hasNext();) {
+            categories.addProvider(iterator.next(), null);
+        }
+    }
+
+    /**
+     * Registers the specified service provider object in all
+     * categories.
+     * 
+     * @param provider the service provider.
+     */
+    public void registerServiceProvider(Object provider) {
+        categories.addProvider(provider, null);
+    }
+
+    /**
+     * Deregisters the specifies service provider from the
+     * specified category.
+     * 
+     * @param provider the service provider to be deregistered.
+     * @param category the specified category.
+     * 
+     * @return true if the provider was already registered 
+     * in the specified category, false otherwise.
+     */
+    public <T> boolean deregisterServiceProvider(T provider, Class<T> category) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Deregisters the specified service provider from all
+     * categories.
+     * 
+     * @param provider the specified service provider.
+     */
+    public void deregisterServiceProvider(Object provider) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an Iterator of registered service providers
+     * in the specified category which satisfy the specified Filter. 
+     * The useOrdering parameter indicates whether the iterator will 
+     * return all of the server provider objects in a set order. 
+     * 
+     * @param category the specified category.
+     * @param filter the specified filter.
+     * @param useOrdering the flag indicating that providers are ordered
+     * in the returned Iterator.
+     * 
+     * @return the iterator of registered service providers.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> Iterator<T> getServiceProviders(Class<T> category, Filter filter, boolean useOrdering) {
+        return new FilteredIterator<T>(filter, (Iterator<T>)categories.getProviders(category, useOrdering));
+    }
+
+    /**
+     * Gets an Iterator of all registered service providers
+     * in the specified category. The useOrdering parameter
+     * indicates whether the iterator will return all of the server 
+     * provider objects in a set order. 
+     * 
+     * @param category the specified category.
+     * @param useOrdering the flag indicating that providers are ordered
+     * in the returned Iterator.
+     * 
+     * @return the Iterator of service providers.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> Iterator<T> getServiceProviders(Class<T> category, boolean useOrdering) {
+        return (Iterator<T>)categories.getProviders(category, useOrdering);
+    }
+
+    /**
+     * Gets the registered service provider object that has the 
+     * specified class type.
+     * 
+     * @param providerClass the specified provider class.
+     * 
+     * @return the service provider object.
+     */
+    public <T> T getServiceProviderByClass(Class<T> providerClass) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Sets an ordering between two service provider objects 
+     * within the specified category. 
+     * 
+     * @param category the specified category.
+     * @param firstProvider the first provider.
+     * @param secondProvider the second provider.
+     * 
+     * @return true if a previously unset order was set.
+     */
+    public <T> boolean setOrdering(Class<T> category, T firstProvider, T secondProvider) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Unsets an ordering between two service provider objects 
+     * within the specified category.
+     * 
+     * @param category the specified category.
+     * @param firstProvider the first provider.
+     * @param secondProvider the second provider.
+     * 
+     * @return true if a previously unset order was removed.
+     */
+    public <T> boolean unsetOrdering(Class<T> category, T firstProvider, T secondProvider) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Deregisters all providers from the specified category.
+     * 
+     * @param category the specified category.
+     */
+    public void deregisterAll(Class<?> category) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Deregister all providers from all categories.
+     */
+    public void deregisterAll() {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Finalizes this object. 
+     * 
+     * @throws Throwable throws if an error occurs during 
+     * finalization.
+     */
+    @Override
+    public void finalize() throws Throwable {
+        //TODO uncomment when deregisterAll is implemented
+        //deregisterAll();
+    }
+
+    /**
+     * Checks whether the specified provider has been already registered.
+     * 
+     * @param provider the provider to be checked.
+     * 
+     * @return true, if the specified provider has been already registered,
+     * false otherwise.
+     */
+    public boolean contains(Object provider) {
+        throw new UnsupportedOperationException("Not supported yet");
+    }
+
+    /**
+     * Gets an iterator of Class objects representing the current 
+     * categories.
+     * 
+     * @return the Iterator of Class objects.
+     */
+    public Iterator<Class<?>> getCategories() {
+        return categories.list();
+    }
+
+    /**
+     * The ServiceRegistry.Filter interface is used by 
+     * ServiceRegistry.getServiceProviders to filter providers according
+     * to the specified criterion. 
+     */
+    public static interface Filter {
+        
+        /**
+         * Returns true if the specified provider satisfies the 
+         * criterion of this Filter.
+         * 
+         * @param provider the provider.
+         * 
+         * @return true if the specified provider satisfies the 
+         * criterion of this Filter, false otherwise.
+         */
+        boolean filter(Object provider);
+    }
+
+    /**
+     * The Class CategoriesMap.
+     */
+    private static class CategoriesMap {
+        
+        /** The categories. */
+        Map<Class<?>, ProvidersMap> categories = new HashMap<Class<?>, ProvidersMap>();
+
+        /** The registry. */
+        ServiceRegistry registry;
+
+        /**
+         * Instantiates a new categories map.
+         * 
+         * @param registry the registry
+         */
+        public CategoriesMap(ServiceRegistry registry) {
+            this.registry = registry;
+        }
+
+        //-- TODO: useOrdering
+        /**
+         * Gets the providers.
+         * 
+         * @param category the category
+         * @param useOrdering the use ordering
+         * 
+         * @return the providers
+         */
+        Iterator<?> getProviders(Class<?> category, boolean useOrdering) {
+            ProvidersMap providers = categories.get(category);
+            if (null == providers) {
+                throw new IllegalArgumentException("Unknown category: " + category);
+            }
+            return providers.getProviders(useOrdering);
+        }
+
+        /**
+         * List.
+         * 
+         * @return the iterator< class<?>>
+         */
+        Iterator<Class<?>> list() {
+            return categories.keySet().iterator();
+        }
+
+        /**
+         * Adds the category.
+         * 
+         * @param category the category
+         */
+        void addCategory(Class<?> category) {
+            categories.put(category, new ProvidersMap());
+        }
+
+        /**
+         * Adds a provider to the category. If <code>category</code> is
+         * <code>null</code> then the provider will be added to all categories
+         * which the provider is assignable from.
+         * 
+         * @param provider provider to add
+         * @param category category to add provider to
+         * 
+         * @return if there were such provider in some category
+         */
+        boolean addProvider(Object provider, Class<?> category) {
+            if (provider == null) {
+                throw new IllegalArgumentException("provider should be != NULL");
+            }
+
+            boolean rt;
+            if (category == null) {
+                rt = findAndAdd(provider);
+            } else {
+                rt  = addToNamed(provider, category);
+            }
+
+            if (provider instanceof RegisterableService) {
+                ((RegisterableService) provider).onRegistration(registry, category);
+            }
+
+            return rt;
+        }
+
+        /**
+         * Adds the to named.
+         * 
+         * @param provider the provider
+         * @param category the category
+         * 
+         * @return true, if successful
+         */
+        private boolean addToNamed(Object provider, Class<?> category) {
+            Object obj = categories.get(category);
+
+            if (null == obj) {
+                throw new IllegalArgumentException("Unknown category: " + category);
+            }
+
+            return ((ProvidersMap) obj).addProvider(provider);
+        }
+
+        /**
+         * Find and add.
+         * 
+         * @param provider the provider
+         * 
+         * @return true, if successful
+         */
+        private boolean findAndAdd(Object provider) {
+            boolean rt = false;
+            for (Entry<Class<?>, ProvidersMap> e : categories.entrySet()) {
+                if (e.getKey().isAssignableFrom(provider.getClass())) {
+                    rt |= e.getValue().addProvider(provider);
+                }
+            }
+            return rt;
+        }
+    }
+
+    /**
+     * The Class ProvidersMap.
+     */
+    private static class ProvidersMap {
+        //-- TODO: providers ordering support
+
+        /** The providers. */
+        Map<Class<?>, Object> providers = new HashMap<Class<?>, Object>();
+
+        /**
+         * Adds the provider.
+         * 
+         * @param provider the provider
+         * 
+         * @return true, if successful
+         */
+        boolean addProvider(Object provider) {
+            return providers.put(provider.getClass(), provider) != null;
+        }
+
+        /**
+         * Gets the provider classes.
+         * 
+         * @return the provider classes
+         */
+        Iterator<Class<?>> getProviderClasses() {
+            return providers.keySet().iterator();
+        }
+
+        //-- TODO ordering
+        /**
+         * Gets the providers.
+         * 
+         * @param userOrdering the user ordering
+         * 
+         * @return the providers
+         */
+        Iterator<?> getProviders(boolean userOrdering) {
+            return providers.values().iterator();
+        }
+    }
+
+    /**
+     * The Class FilteredIterator.
+     */
+    private static class FilteredIterator<E> implements Iterator<E> {
+
+        /** The filter. */
+        private Filter filter;
+        
+        /** The backend. */
+        private Iterator<E> backend;
+        
+        /** The next obj. */
+        private E nextObj;
+
+        /**
+         * Instantiates a new filtered iterator.
+         * 
+         * @param filter the filter
+         * @param backend the backend
+         */
+        public FilteredIterator(Filter filter, Iterator<E> backend) {
+            this.filter = filter;
+            this.backend = backend;
+            findNext();
+        }
+
+        /**
+         * Next.
+         * 
+         * @return the e
+         */
+        public E next() {
+            if (nextObj == null) {
+                throw new NoSuchElementException();
+            }
+            E tmp = nextObj;
+            findNext();
+            return tmp;
+        }
+
+        /**
+         * Checks for next.
+         * 
+         * @return true, if successful
+         */
+        public boolean hasNext() {
+            return nextObj != null;
+        }
+
+        /**
+         * Removes the.
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Sets nextObj to a next provider matching the criterion given by the filter.
+         */
+        private void findNext() {
+            nextObj = null;
+            while (backend.hasNext()) {
+                E o = backend.next();
+                if (filter.filter(o)) {
+                    nextObj = o;
+                    return;
+                }
+            }
+        }
+    }
+}
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();        
+    }
+}
diff --git a/awt/org/apache/harmony/awt/ChoiceStyle.java b/awt/org/apache/harmony/awt/ChoiceStyle.java
new file mode 100644
index 0000000..93b7aad
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ChoiceStyle.java
@@ -0,0 +1,33 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+/**
+ * ChoiceStyle.
+ * Is used to define custom choice properties:
+ * width and x screen coordinate of the list popup window. 
+ */
+public interface ChoiceStyle {
+
+    int getPopupX(int x, int width, int choiceWidth, int screenWidth);
+    int getPopupWidth(int choiceWidth);
+
+}
diff --git a/awt/org/apache/harmony/awt/ClipRegion.java b/awt/org/apache/harmony/awt/ClipRegion.java
new file mode 100644
index 0000000..c89a81d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ClipRegion.java
@@ -0,0 +1,84 @@
+/*
+ *  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 Pavel Dolgov, Anton Avtamonov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+import java.awt.Component;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class ClipRegion extends Rectangle {
+    private final MultiRectArea clip;
+
+    public ClipRegion(final MultiRectArea clip) {
+        this.clip = new MultiRectArea(clip);
+        setBounds(clip.getBounds());
+    }
+
+    public MultiRectArea getClip() {
+        return clip;
+    }
+
+    @Override
+    public String toString() {
+        String str = clip.toString();
+        int i = str.indexOf('[');
+        str = str.substring(i);
+        if (clip.getRectCount() == 1) {
+            str = str.substring(1, str.length() - 1);
+        }
+        return getClass().getName() + str;
+    }
+
+
+    public void convertRegion(final Component child, final Component parent) {
+        convertRegion(child, clip, parent);
+    }
+
+    public void intersect(final Rectangle rect) {
+        clip.intersect(rect);
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return clip.isEmpty();
+    }
+
+    public static void convertRegion(final Component child,
+                                     final MultiRectArea region,
+                                     final Component parent) {
+        int x = 0, y = 0;
+        Component c = child;
+        //???AWT
+        /*
+        for (; c != null && c != parent; c = c.getParent()) {
+            x += c.getX();
+            y += c.getY();
+        }
+        */
+        if (c == null) {
+            // awt.51=Component expected to be a parent
+            throw new IllegalArgumentException(Messages.getString("awt.51")); //$NON-NLS-1$
+        }
+        region.translate(x, y);
+    }
+}
diff --git a/awt/org/apache/harmony/awt/ComponentInternals.java b/awt/org/apache/harmony/awt/ComponentInternals.java
new file mode 100644
index 0000000..c359784
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ComponentInternals.java
@@ -0,0 +1,212 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+//???AWT
+//import java.awt.Component;
+//import java.awt.Container;
+//import java.awt.Dialog;
+import java.awt.Dimension;
+//import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+//import java.awt.Window;
+//import java.awt.Choice;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+//import org.apache.harmony.awt.text.TextFieldKit;
+//import org.apache.harmony.awt.text.TextKit;
+//import org.apache.harmony.awt.wtk.NativeWindow;
+
+import org.apache.harmony.luni.util.NotImplementedException;
+
+/**
+ *  The accessor to AWT private API
+ */
+public abstract class ComponentInternals {
+
+    /**
+     * @return the ComponentInternals instance to serve the requests
+     */
+    public static ComponentInternals getComponentInternals() {
+        return ContextStorage.getComponentInternals();
+    }
+
+    /**
+     * This method must be called by AWT to establish the connection
+     * @param internals - implementation of ComponentInternals created by AWT
+     */
+    public static void setComponentInternals(ComponentInternals internals) {
+        ContextStorage.setComponentInternals(internals);
+    }
+
+    /**
+     * The accessor to native resource connected to a component.
+     * It returns non-<code>null</code> value only if component
+     * already has the native resource
+     */
+    //public abstract NativeWindow getNativeWindow(Component component);
+
+    /**
+     * Connect Window object to existing native resource
+     * @param nativeWindowId - id of native window to attach
+     * @return Window object with special behaviour that
+     * restricts manupulation with that window
+     */
+    //public abstract Window attachNativeWindow(long nativeWindowId);
+
+    /**
+     * Start mouse grab in "client" mode.
+     * All mouse events in AWT components will be reported as usual,
+     * mouse events that occured outside of AWT components will be sent to
+     * the window passed as grabWindow parameter. When mouse grab is canceled
+     * (because of click in non-AWT window or by task switching)
+     * the whenCanceled callback is called
+     *
+     * @param grabWindow - window that will own the grab
+     * @param whenCanceled - callback called when grab is canceled by user's action
+     */
+    //public abstract void startMouseGrab(Window grabWindow, Runnable whenCanceled);
+
+    /**
+     * End mouse grab and resume normal processing of mouse events
+     */
+    //public abstract void endMouseGrab();
+
+    /**
+     * Set the <code>popup</code> flag of the window to true.
+     * This window won't be controlled by window manager on Linux.
+     * Call this method before the window is shown first time
+     * @param window - the window that should become popup one
+     */
+    //public abstract void makePopup(Window window);
+
+    /**
+     * This method must be called by Graphics at the beginning of drawImage()
+     * to store image drawing parameters (defined by application developer) in component
+     *
+     * @param comp - component that draws the image
+     * @param image - image to be drawn
+     * @param destLocation - location of the image upon the component's surface. Never null.
+     * @param destSize - size of the component's area to be filled with the image.
+     *                  Equals to null if size parameters omitted in drawImage.
+     * @param source - area of the image to be drawn on the component.
+     *                  Equals to null if src parameters omitted in drawImage.
+     */
+    /*
+    public abstract void onDrawImage(Component comp, Image image, Point destLocation,
+            Dimension destSize, Rectangle source);
+*/
+    /**
+     * Sets system's caret position.
+     * This method should be called by text component to synchronize our caret position
+     * with system's caret position.
+     * @param x
+     * @param y
+     */
+    //public abstract void setCaretPos(Component c, int x, int y);
+
+    /**
+     * NEVER USE IT. FORGET IT. IT DOES NOT EXIST.
+     * See Toolkit.unsafeInvokeAndWait(Runnable).
+     *
+     * Accessor for Toolkit.unsafeInvokeAndWait(Runnable) method.
+     * For use in exceptional cases only.
+     * Read comments for Toolkit.unsafeInvokeAndWait(Runnable) before use.
+     */
+    /*
+    public abstract void unsafeInvokeAndWait(Runnable runnable)
+            throws InterruptedException, InvocationTargetException;
+
+    public abstract TextKit getTextKit(Component comp);
+
+    public abstract void setTextKit(Component comp, TextKit kit);
+
+    public abstract TextFieldKit getTextFieldKit(Component comp);
+
+    public abstract void setTextFieldKit(Component comp, TextFieldKit kit);
+*/
+    /**
+     * Terminate event dispatch thread, completely destroy AWT context.<br>
+     * Intended for multi-context mode, in single-context mode does nothing.
+     *
+     */
+    public abstract void shutdown();
+
+    /**
+     * Sets mouse events preprocessor for event queue
+     */
+    //public abstract void setMouseEventPreprocessor(MouseEventPreprocessor preprocessor);
+
+    /**
+     * Create customized Choice using style
+     */
+    //public abstract Choice createCustomChoice(ChoiceStyle style);
+
+    //public abstract Insets getNativeInsets(Window w);
+
+    /**
+     * Region to be repainted (could be null). Use this in overridden repaint()
+     */
+    //public abstract MultiRectArea getRepaintRegion(Component c);
+
+    //public abstract MultiRectArea subtractPendingRepaintRegion(Component c, MultiRectArea mra);
+
+    /**
+     * Returns true if the window was at least once painted due to native paint events
+     */
+    //public abstract boolean wasPainted(Window w);
+
+    /**
+     * The component's region hidden behind top-level windows
+     * (belonging to both this Java app and all other apps), and behind
+     * heavyweight components overlapping with passed component
+     */
+    //public abstract MultiRectArea getObscuredRegion(Component c);
+    
+    /**
+     * An accessor to Container.addObscuredRegions() method
+     * @see java.awt.Container#addObscuredRegions(MultiRectArea, Component)
+     */
+    //public abstract void addObscuredRegions(MultiRectArea mra, Component c, Container container);
+    
+    /**
+     * Makes it possible to call protected Toolkit.setDesktopProperty()
+     * method from any class outside of java.awt package
+     */
+    public abstract void setDesktopProperty(String name, Object value);
+    
+    /**
+     * Makes it possible to start/stop dialog modal loop
+     * from anywhere outside of java.awt package
+     */
+    //public abstract void runModalLoop(Dialog dlg);
+    //public abstract void endModalLoop(Dialog dlg);
+    
+    /**
+     * Sets component's visible flag only
+     * (the component is not actually shown/hidden)
+     */
+    //public abstract void setVisibleFlag(Component comp, boolean visible);
+    
+}
diff --git a/awt/org/apache/harmony/awt/ContextStorage.java b/awt/org/apache/harmony/awt/ContextStorage.java
new file mode 100644
index 0000000..d44648a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ContextStorage.java
@@ -0,0 +1,154 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+import java.awt.*;
+
+//???AWT
+//import org.apache.harmony.awt.datatransfer.*;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.awt.wtk.*;
+
+
+public final class ContextStorage {
+
+    private static volatile boolean multiContextMode = false;
+    private volatile boolean shutdownPending = false;
+
+    private static final ContextStorage globalContext = new ContextStorage();
+
+    private Toolkit toolkit;
+    private ComponentInternals componentInternals;
+    //???AWT: private DTK dtk;
+    private WTK wtk;
+    private GraphicsEnvironment graphicsEnvironment;
+
+    private class ContextLock {}
+    private final Object contextLock = new ContextLock();
+    private final Synchronizer synchronizer = new Synchronizer();
+
+    public static void activateMultiContextMode() {
+        // TODO: checkPermission
+        multiContextMode = true;
+    }
+
+    public static void setDefaultToolkit(Toolkit newToolkit) {
+        // TODO: checkPermission
+        getCurrentContext().toolkit = newToolkit;
+    }
+
+    public static Toolkit getDefaultToolkit() {
+        return getCurrentContext().toolkit;
+    }
+
+    //???AWT
+    /*
+    public static void setDTK(DTK dtk) {
+        // TODO: checkPermission
+        getCurrentContext().dtk = dtk;
+    }
+
+    public static DTK getDTK() {
+        return getCurrentContext().dtk;
+    }
+    */
+
+    public static Synchronizer getSynchronizer() {
+        return getCurrentContext().synchronizer;
+    }
+
+    public static ComponentInternals getComponentInternals() {
+        return getCurrentContext().componentInternals;
+    }
+
+    static void setComponentInternals(ComponentInternals internals) {
+        // TODO: checkPermission
+        getCurrentContext().componentInternals = internals;
+    }
+
+    public static Object getContextLock() {
+        return getCurrentContext().contextLock;
+    }
+
+    public static WindowFactory getWindowFactory() {
+        return getCurrentContext().wtk.getWindowFactory();
+    }
+
+    public static void setWTK(WTK wtk) {
+        getCurrentContext().wtk = wtk;
+    }
+
+    public static NativeIM getNativeIM() {
+        return getCurrentContext().wtk.getNativeIM();
+    }
+
+    public static NativeEventQueue getNativeEventQueue() {
+        return getCurrentContext().wtk.getNativeEventQueue();
+    }
+
+    public static GraphicsEnvironment getGraphicsEnvironment() {
+        return getCurrentContext().graphicsEnvironment;
+    }
+
+    public static void setGraphicsEnvironment(GraphicsEnvironment environment) {
+        getCurrentContext().graphicsEnvironment = environment;
+    }
+
+    private static ContextStorage getCurrentContext() {
+        return multiContextMode ? getContextThreadGroup().context : globalContext;
+    }
+
+    private static ContextThreadGroup getContextThreadGroup() {
+
+        Thread thread = Thread.currentThread();
+        ThreadGroup group = thread.getThreadGroup();
+        while (group != null) {
+            if (group instanceof ContextThreadGroup) {
+                return (ContextThreadGroup)group;
+            }
+            group = group.getParent();
+        }
+        // awt.59=Application has run out of context thread group
+        throw new RuntimeException(Messages.getString("awt.59")); //$NON-NLS-1$
+    }
+    
+    public static boolean shutdownPending() {
+        return getCurrentContext().shutdownPending;
+    }
+
+    void shutdown() {
+        if (!multiContextMode) {
+            return;
+        }
+        shutdownPending = true;
+
+        //???AWT: componentInternals.shutdown();
+
+        synchronized(contextLock) {
+            toolkit = null;
+            componentInternals = null;
+            //???AWT: dtk = null;
+            wtk = null;
+            graphicsEnvironment = null;
+        }
+    }
+    
+}
diff --git a/awt/org/apache/harmony/awt/ContextThreadGroup.java b/awt/org/apache/harmony/awt/ContextThreadGroup.java
new file mode 100644
index 0000000..4f0af52
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ContextThreadGroup.java
@@ -0,0 +1,34 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+public class ContextThreadGroup extends ThreadGroup {
+
+    final ContextStorage context = new ContextStorage();
+
+    public ContextThreadGroup(String name) {
+        super(name);
+    }
+
+    public void dispose() {
+        context.shutdown();
+    }
+}
diff --git a/awt/org/apache/harmony/awt/ListenerList.java b/awt/org/apache/harmony/awt/ListenerList.java
new file mode 100644
index 0000000..f5c55f1
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ListenerList.java
@@ -0,0 +1,194 @@
+/*
+ *  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 org.apache.harmony.awt;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * List of AWT listeners. It is for 3 purposes.
+ * 1. To support list modification from listeners
+ * 2. To ensure call for all listeners as atomic operation
+ * 3. To support system listeners that are needed for built-in AWT components
+ */
+public class ListenerList<T extends EventListener> implements Serializable {
+    private static final long serialVersionUID = 9180703263299648154L;
+
+    private transient ArrayList<T> systemList;
+    private transient ArrayList<T> userList;
+    
+    public ListenerList() {
+        super();
+    }
+
+    /**
+     * Adds system listener to this list.
+     *
+     * @param listener - listener to be added.
+     */
+    public void addSystemListener(T listener) {
+        if (systemList == null) {
+            systemList = new ArrayList<T>();
+        }
+        systemList.add(listener);
+    }
+
+    /**
+     * Adds user (public) listener to this list.
+     *
+     * @param listener - listener to be added.
+     */
+    public void addUserListener(T listener) {
+        if (listener == null) {
+            return;
+        }
+        // transactionally replace old list
+        synchronized (this) {
+            if (userList == null) {
+                userList = new ArrayList<T>();
+                userList.add(listener);
+                return;
+            }
+            ArrayList<T> newList = new ArrayList<T>(userList);
+            newList.add(listener);
+            userList = newList;
+        }
+    }
+
+    /**
+     * Removes user (public) listener to this list.
+     *
+     * @param listener - listener to be removed.
+     */
+    public void removeUserListener(Object listener) {
+        if (listener == null) {
+            return;
+        }
+        // transactionally replace old list
+        synchronized (this) {
+            if (userList == null || !userList.contains(listener)) {
+                return;
+            }
+            ArrayList<T> newList = new ArrayList<T>(userList);
+            newList.remove(listener);
+            userList = (newList.size() > 0 ? newList : null);
+        }
+    }
+
+    /**
+     * Gets all user (public) listeners in one array.
+     *
+     * @param emptyArray - empty array, it's for deriving particular listeners class.
+     * @return array of all user listeners.
+     */
+    public <AT> AT[] getUserListeners(AT[] emptyArray){
+        synchronized (this) {
+            return (userList != null ? userList.toArray(emptyArray) : emptyArray);
+
+        }
+    }
+
+    /**
+     * Gets all user (public) listeners in one list.
+     *
+     * @return list of all user listeners.
+     */
+    public List<T> getUserListeners() {
+        synchronized (this) {
+            if (userList == null || userList.isEmpty()) {
+                return Collections.emptyList();
+            }
+            return new ArrayList<T>(userList);
+        }
+    }
+    
+    public List<T> getSystemListeners() {
+        synchronized (this) {
+            if (systemList == null || systemList.isEmpty()) {
+                return Collections.emptyList();
+            }
+            return new ArrayList<T>(systemList);
+        }
+    }
+
+    /**
+     * Gets iterator for user listeners.
+     *
+     * @return iterator for user listeners.
+     */
+    public Iterator<T> getUserIterator() {
+        synchronized (this) {
+            if (userList == null) {
+                List<T> emptyList = Collections.emptyList();
+                return emptyList.iterator();
+            }
+            return new ReadOnlyIterator<T>(userList.iterator());
+        }
+    }
+
+    /**
+     * Gets iterator for system listeners.
+     *
+     * @return iterator for system listeners.
+     */
+    public Iterator<T> getSystemIterator() {
+        return systemList.iterator();
+    }
+
+    private static ArrayList<?> getOnlySerializable(ArrayList<?> list) {
+        if (list == null) {
+            return null;
+        }
+
+        ArrayList<Object> result = new ArrayList<Object>();
+        for (Iterator<?> it = list.iterator(); it.hasNext();) {
+            Object obj = it.next();
+            if (obj instanceof Serializable) {
+                result.add(obj);
+            }
+        }
+
+        return (result.size() != 0) ? result : null;
+    }
+
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+
+        stream.defaultWriteObject();
+
+        stream.writeObject(getOnlySerializable(systemList));
+        stream.writeObject(getOnlySerializable(userList));
+    }
+
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream stream)
+            throws IOException, ClassNotFoundException {
+
+        stream.defaultReadObject();
+
+        systemList = (ArrayList<T>)stream.readObject();
+        userList = (ArrayList<T>)stream.readObject();
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/ReadOnlyIterator.java b/awt/org/apache/harmony/awt/ReadOnlyIterator.java
new file mode 100644
index 0000000..671653f
--- /dev/null
+++ b/awt/org/apache/harmony/awt/ReadOnlyIterator.java
@@ -0,0 +1,53 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt;
+
+import java.util.Iterator;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * ReadOnlyIterator
+ */
+public final class ReadOnlyIterator<E> implements Iterator<E> {
+
+    private final Iterator<E> it;
+
+    public ReadOnlyIterator(Iterator<E> it) {
+        if (it == null) {
+            throw new NullPointerException();
+        }
+        this.it = it;
+    }
+
+    public void remove() {
+        // awt.50=Iterator is read-only
+        throw new UnsupportedOperationException(Messages.getString("awt.50")); //$NON-NLS-1$
+    }
+
+    public boolean hasNext() {
+        return it.hasNext();
+    }
+
+    public E next() {
+        return it.next();
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/AwtImageBackdoorAccessor.java b/awt/org/apache/harmony/awt/gl/AwtImageBackdoorAccessor.java
new file mode 100644
index 0000000..bd5f6c6
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/AwtImageBackdoorAccessor.java
@@ -0,0 +1,65 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 23.11.2005
+ *
+ */
+
+
+package org.apache.harmony.awt.gl;
+
+import java.awt.Image;
+import java.awt.image.DataBuffer;
+import java.awt.image.IndexColorModel;
+import java.awt.image.DataBufferInt;
+
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+
+/**
+ * This class give an opportunity to get access to private data of 
+ * some java.awt.image classes 
+ * Implementation of this class placed in java.awt.image package
+ */
+
+public abstract class AwtImageBackdoorAccessor {
+
+    static protected AwtImageBackdoorAccessor inst;
+
+    public static AwtImageBackdoorAccessor getInstance(){
+        // First we need to run the static initializer in the DataBuffer class to resolve inst.
+        new DataBufferInt(0);
+        return inst;
+    }
+
+    public abstract Surface getImageSurface(Image image);
+    public abstract boolean isGrayPallete(IndexColorModel icm);
+
+    public abstract Object getData(DataBuffer db);
+    public abstract int[] getDataInt(DataBuffer db);
+    public abstract byte[] getDataByte(DataBuffer db);
+    public abstract short[] getDataShort(DataBuffer db);
+    public abstract short[] getDataUShort(DataBuffer db);
+    public abstract double[] getDataDouble(DataBuffer db);
+    public abstract float[] getDataFloat(DataBuffer db);
+    public abstract void releaseData(DataBuffer db);
+    
+    public abstract void addDataBufferListener(DataBuffer db, DataBufferListener listener);
+    public abstract void removeDataBufferListener(DataBuffer db);
+    public abstract void validate(DataBuffer db);
+}
diff --git a/awt/org/apache/harmony/awt/gl/CommonGraphics2D.java b/awt/org/apache/harmony/awt/gl/CommonGraphics2D.java
new file mode 100644
index 0000000..a33c38b
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/CommonGraphics2D.java
@@ -0,0 +1,1132 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.PaintContext;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.ImageObserver;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.WritableRaster;
+import java.awt.image.renderable.RenderableImage;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.RoundRectangle2D;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.image.OffscreenImage;
+import org.apache.harmony.awt.gl.render.Blitter;
+import org.apache.harmony.awt.gl.render.JavaArcRasterizer;
+import org.apache.harmony.awt.gl.render.JavaLineRasterizer;
+import org.apache.harmony.awt.gl.render.JavaShapeRasterizer;
+import org.apache.harmony.awt.gl.render.JavaTextRenderer;
+import org.apache.harmony.awt.gl.render.NullBlitter;
+
+/*
+ * List of abstract methods to implement in subclusses
+ * Graphics.copyArea(int x, int y, int width, int height, int dx, int dy)
+ * Graphics.create()
+ * Graphics2D.getDeviceConfiguration()
+ * CommonGraphics2D.fillMultiRectAreaColor(MultiRectArea mra);
+ * CommonGraphics2D.fillMultiRectAreaPaint(MultiRectArea mra);
+ */
+
+/**
+ * CommonGraphics2D class is a super class for all system-dependent
+ * implementations. It implements major part of Graphics and Graphics2D
+ * abstract methods.
+ * <h2>CommonGraphics2D Class Internals</h2>
+ * <h3>Line and Shape Rasterizers</h3>
+ * <p>
+ * The CommonGraphics2D class splits all shapes into a set of rectangles 
+ * to unify the drawing process for different operating systems and architectures. 
+ * For this purpose Java 2D* uses the JavaShapeRasterizer and the JavaLineRasterizer 
+ * classes from the org.apache.harmony.awt.gl.render package. The JavaShapeRasterizer 
+ * class splits an object implementing a Shape interface into a set of rectangles and 
+ * produces a MultiRectArea object. The JavaLineRasterizer class makes line drawing 
+ * more accurate and processes lines with strokes, which are instances of the BasicStroke 
+ * class.
+ * </p>
+ * <p>
+ * To port the shape drawing to another platform you just need to override 
+ * rectangle-drawing methods. However, if your operating system has functions to draw 
+ * particular shapes, you can optimize your subclass of the CommonGraphics2D class by 
+ * using this functionality in overridden methods.
+ * </p>
+
+ * <h3>Blitters</h3>
+ * <p>
+ * Blitter classes draw images on the display or buffered images. All blitters inherit 
+ * the org.apache.harmony.awt.gl.render.Blitter interface.
+ * </p>
+ * <p>Blitters are divided into:
+ * <ul>
+ * <li>Native blitters for simple types of images, which the underlying native library 
+ * can draw.</li> 
+ * <li>Java* blitters for those types of images, which the underlying native library 
+ * cannot handle.</li>
+ * </ul></p>
+ * <p>
+ * DRL Java 2D* also uses blitters to fill the shapes and the user-defined subclasses 
+ * of the java.awt.Paint class with paints, which the system does not support.
+ * </p>
+ *
+ *<h3>Text Renderers</h3>
+ *<p>
+ *Text renderers draw strings and glyph vectors. All text renderers are subclasses 
+ *of the org.apache.harmony.awt.gl.TextRenderer class.
+ *</p>
+ *
+ */
+public abstract class CommonGraphics2D extends Graphics2D {
+    protected Surface dstSurf = null;
+    protected Blitter blitter = NullBlitter.getInstance();
+    protected RenderingHints hints = new RenderingHints(null);
+
+    // Clipping things
+    protected MultiRectArea clip = null;
+
+    protected Paint paint = Color.WHITE;
+    protected Color fgColor = Color.WHITE;
+    protected Color bgColor = Color.BLACK;
+
+    protected Composite composite = AlphaComposite.SrcOver;
+
+    protected Stroke stroke = new BasicStroke();
+
+    //TODO: Think more about FontRenderContext
+    protected FontRenderContext frc = new FontRenderContext(null, false, false);
+
+    protected JavaShapeRasterizer jsr = new JavaShapeRasterizer();
+
+    protected Font font = new Font("Dialog", Font.PLAIN, 12);; //$NON-NLS-1$
+
+    protected TextRenderer jtr = JavaTextRenderer.inst;
+
+    // Current graphics transform
+    protected AffineTransform transform = new AffineTransform();
+    protected double[] matrix = new double[6];
+
+    // Original user->device translation as transform and point
+    //public AffineTransform origTransform = new AffineTransform();
+    public Point origPoint = new Point(0, 0);
+
+
+    // Print debug output or not
+    protected static final boolean debugOutput = "1".equals(System.getProperty("g2d.debug")); //$NON-NLS-1$ //$NON-NLS-2$
+
+    // Constructors
+    protected CommonGraphics2D() {
+    }
+
+    protected CommonGraphics2D(int tx, int ty) {
+        this(tx, ty, null);
+    }
+
+    protected CommonGraphics2D(int tx, int ty, MultiRectArea clip) {
+        setTransform(AffineTransform.getTranslateInstance(tx, ty));
+        //origTransform = AffineTransform.getTranslateInstance(tx, ty);
+        origPoint = new Point(tx, ty);
+        setClip(clip);
+    }
+
+    // Public methods
+    @Override
+    public void addRenderingHints(Map<?,?> hints) {
+        this.hints.putAll(hints);
+    }
+
+    @Override
+    public void clearRect(int x, int y, int width, int height) {
+        Color c = getColor();
+        Paint p = getPaint();
+        setColor(getBackground());
+        fillRect(x, y, width, height);
+        setColor(c);
+        setPaint(p);
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.clearRect("+x+", "+y+", "+width+", "+height+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+    }
+
+    @Override
+    public void clipRect(int x, int y, int width, int height) {
+        clip(new Rectangle(x, y, width, height));
+    }
+
+
+    @Override
+    public void clip(Shape s) {
+        if (s == null) {
+            clip = null;
+            return;
+        }
+
+        MultiRectArea mra = null;
+        if (s instanceof MultiRectArea) {
+            mra = new MultiRectArea((MultiRectArea)s);
+            mra.translate((int)transform.getTranslateX(), (int)transform.getTranslateY());
+        } else {
+            int type = transform.getType();
+            if(s instanceof Rectangle && (type & (AffineTransform.TYPE_IDENTITY |
+                AffineTransform.TYPE_TRANSLATION)) != 0){
+                    mra = new MultiRectArea((Rectangle)s);
+                    if(type == AffineTransform.TYPE_TRANSLATION){
+                        mra.translate((int)transform.getTranslateX(), (int)transform.getTranslateY());
+                    }
+            } else {
+                s = transform.createTransformedShape(s);
+                mra = jsr.rasterize(s, 0.5);
+            }
+        }
+
+        if (clip == null) {
+            setTransformedClip(mra);
+        } else {
+            clip.intersect(mra);
+            setTransformedClip(clip);
+        }
+    }
+
+    @Override
+    public void dispose() {
+        // Do nothing for Java only classes
+    }
+
+
+
+
+    /***************************************************************************
+     *
+     *  Draw methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public void draw(Shape s) {
+        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1) {
+            //TODO: Think about drawing the shape in one fillMultiRectArea call
+            BasicStroke bstroke = (BasicStroke)stroke;
+            JavaLineRasterizer.LineDasher ld = (bstroke.getDashArray() == null)?null:new JavaLineRasterizer.LineDasher(bstroke.getDashArray(), bstroke.getDashPhase());
+            PathIterator pi = s.getPathIterator(transform, 0.5);
+            float []points = new float[6];
+            int x1 = Integer.MIN_VALUE;
+            int y1 = Integer.MIN_VALUE;
+            int cx1 = Integer.MIN_VALUE;
+            int cy1 = Integer.MIN_VALUE;
+            while (!pi.isDone()) {
+                switch (pi.currentSegment(points)) {
+                    case PathIterator.SEG_MOVETO:
+                        x1 = (int)Math.floor(points[0]);
+                        y1 = (int)Math.floor(points[1]);
+                        cx1 = x1;
+                        cy1 = y1;
+                        break;
+                    case PathIterator.SEG_LINETO:
+                        int x2 = (int)Math.floor(points[0]);
+                        int y2 = (int)Math.floor(points[1]);
+                        fillMultiRectArea(JavaLineRasterizer.rasterize(x1, y1, x2, y2, null, ld, false));
+                        x1 = x2;
+                        y1 = y2;
+                        break;
+                    case PathIterator.SEG_CLOSE:
+                        x2 = cx1;
+                        y2 = cy1;
+                        fillMultiRectArea(JavaLineRasterizer.rasterize(x1, y1, x2, y2, null, ld, false));
+                        x1 = x2;
+                        y1 = y2;
+                        break;
+                }
+                pi.next();
+            }
+        } else {
+            s = stroke.createStrokedShape(s);
+            s = transform.createTransformedShape(s);
+            fillMultiRectArea(jsr.rasterize(s, 0.5));
+        }
+    }
+
+    @Override
+    public void drawArc(int x, int y, int width, int height, int sa, int ea) {
+        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1 &&
+                ((BasicStroke)stroke).getDashArray() == null && 
+                (transform.isIdentity() || transform.getType() == AffineTransform.TYPE_TRANSLATION)) {
+            Point p = new Point(x, y);
+            transform.transform(p, p);
+            MultiRectArea mra = JavaArcRasterizer.rasterize(x, y, width, height, sa, ea, clip);
+            fillMultiRectArea(mra);
+            return;
+        }
+        draw(new Arc2D.Float(x, y, width, height, sa, ea, Arc2D.OPEN));
+    }
+
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, Color bgcolor,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h, (AffineTransform) transform.clone(),
+                    composite, bgcolor, clip);
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, ImageObserver imageObserver) {
+        return drawImage(image, x, y, null, imageObserver);
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, int width, int height,
+            Color bgcolor, ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(width == 0 || height == 0) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            if(w == width && h == height){
+                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                        (AffineTransform) transform.clone(),
+                        composite, bgcolor, clip);
+            }else{
+                AffineTransform xform = new AffineTransform();
+                xform.setToScale((float)width / w, (float)height / h);
+                blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                        (AffineTransform) transform.clone(),
+                        xform, composite, bgcolor, clip);
+            }
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int x, int y, int width, int height,
+            ImageObserver imageObserver) {
+        return drawImage(image, x, y, width, height, null, imageObserver);
+    }
+
+    @Override
+    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
+            int sx1, int sy1, int sx2, int sy2, Color bgcolor,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(dx1 == dx2 || dy1 == dy2 || sx1 == sx2 || sy1 == sy2) {
+            return true;
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+
+            int dstX = dx1;
+            int dstY = dy1;
+            int srcX = sx1;
+            int srcY = sy1;
+
+            int dstW = dx2 - dx1;
+            int dstH = dy2 - dy1;
+            int srcW = sx2 - sx1;
+            int srcH = sy2 - sy1;
+
+            if(srcW == dstW && srcH == dstH){
+                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
+                        (AffineTransform) transform.clone(),
+                        composite, bgcolor, clip);
+            }else{
+                AffineTransform xform = new AffineTransform();
+                xform.setToScale((float)dstW / srcW, (float)dstH / srcH);
+                blitter.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, srcW, srcH,
+                        (AffineTransform) transform.clone(),
+                        xform, composite, bgcolor, clip);
+            }
+        }
+        return done;
+    }
+
+    @Override
+    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
+            int sx1, int sy1, int sx2, int sy2, ImageObserver imageObserver) {
+
+        return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
+                imageObserver);
+     }
+
+    @Override
+    public void drawImage(BufferedImage bufImage, BufferedImageOp op,
+            int x, int y) {
+
+        if(bufImage == null) {
+            return;
+        }
+
+        if(op == null) {
+            drawImage(bufImage, x, y, null);
+        } else if(op instanceof AffineTransformOp){
+            AffineTransformOp atop = (AffineTransformOp) op;
+            AffineTransform xform = atop.getTransform();
+            Surface srcSurf = Surface.getImageSurface(bufImage);
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                    (AffineTransform) transform.clone(), xform,
+                    composite, null, clip);
+        } else {
+            bufImage = op.filter(bufImage, null);
+            Surface srcSurf = Surface.getImageSurface(bufImage);
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                    (AffineTransform) transform.clone(),
+                    composite, null, clip);
+        }
+    }
+
+    @Override
+    public boolean drawImage(Image image, AffineTransform trans,
+            ImageObserver imageObserver) {
+
+        if(image == null) {
+            return true;
+        }
+        if(trans == null || trans.isIdentity()) {
+            return drawImage(image, 0, 0, imageObserver);
+        }
+
+        boolean done = false;
+        boolean somebits = false;
+        Surface srcSurf = null;
+        if(image instanceof OffscreenImage){
+            OffscreenImage oi = (OffscreenImage) image;
+            if((oi.getState() & ImageObserver.ERROR) != 0) {
+                return false;
+            }
+            done = oi.prepareImage(imageObserver);
+            somebits = (oi.getState() & ImageObserver.SOMEBITS) != 0;
+            srcSurf = oi.getImageSurface();
+        }else{
+            done = true;
+            srcSurf = Surface.getImageSurface(image);
+        }
+
+        if(done || somebits) {
+            int w = srcSurf.getWidth();
+            int h = srcSurf.getHeight();
+            AffineTransform xform = (AffineTransform) transform.clone();
+            xform.concatenate(trans);
+            blitter.blit(0, 0, srcSurf, 0, 0, dstSurf, w, h, xform, composite,
+                    null, clip);
+        }
+        return done;
+    }
+
+    @Override
+    public void drawLine(int x1, int y1, int x2, int y2) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.drawLine("+x1+", "+y1+", "+x2+", "+y2+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+
+        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1) {
+            BasicStroke bstroke = (BasicStroke)stroke;
+            Point p1 = new Point(x1, y1);
+            Point p2 = new Point(x2, y2);
+            transform.transform(p1, p1);
+            transform.transform(p2, p2);
+            JavaLineRasterizer.LineDasher ld = (bstroke.getDashArray() == null)?null:new JavaLineRasterizer.LineDasher(bstroke.getDashArray(), bstroke.getDashPhase());
+            MultiRectArea mra = JavaLineRasterizer.rasterize(p1.x, p1.y, p2.x, p2.y, null, ld, false);
+            fillMultiRectArea(mra);
+            return;
+        }
+        draw(new Line2D.Float(x1, y1, x2, y2));
+    }
+
+    @Override
+    public void drawOval(int x, int y, int width, int height) {
+        if (stroke instanceof BasicStroke && ((BasicStroke)stroke).getLineWidth() <= 1 &&
+                ((BasicStroke)stroke).getDashArray() == null && 
+                (transform.isIdentity() || transform.getType() == AffineTransform.TYPE_TRANSLATION)) {
+            Point p = new Point(x, y);
+            transform.transform(p, p);
+            MultiRectArea mra = JavaArcRasterizer.rasterize(x, y, width, height, 0, 360, clip);
+            fillMultiRectArea(mra);
+            return;
+        }
+        draw(new Ellipse2D.Float(x, y, width, height));
+    }
+
+    @Override
+    public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) {
+        draw(new Polygon(xpoints, ypoints, npoints));
+    }
+
+    @Override
+    public void drawPolygon(Polygon polygon) {
+        draw(polygon);
+    }
+
+    @Override
+    public void drawPolyline(int[] xpoints, int[] ypoints, int npoints) {
+        for (int i = 0; i < npoints-1; i++) {
+            drawLine(xpoints[i], ypoints[i], xpoints[i+1], ypoints[i+1]);
+        }
+    }
+
+    @Override
+    public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
+        if (img == null) {
+            return;
+        }
+
+        double scaleX = xform.getScaleX();
+        double scaleY = xform.getScaleY();
+        if (scaleX == 1 && scaleY == 1) {
+            drawRenderedImage(img.createDefaultRendering(), xform);
+        } else {
+            int width = (int)Math.round(img.getWidth()*scaleX);
+            int height = (int)Math.round(img.getHeight()*scaleY);
+            xform = (AffineTransform)xform.clone();
+            xform.scale(1, 1);
+            drawRenderedImage(img.createScaledRendering(width, height, null), xform);
+        }
+    }
+
+    @Override
+    public void drawRenderedImage(RenderedImage rimg, AffineTransform xform) {
+        if (rimg == null) {
+            return;
+        }
+
+        Image img = null;
+
+        if (rimg instanceof Image) {
+            img = (Image)rimg;
+        } else {
+            //TODO: Create new class to provide Image interface for RenderedImage or rewrite this method
+            img = new BufferedImage(rimg.getColorModel(), rimg.copyData(null), false, null);
+        }
+
+        drawImage(img, xform, null);
+    }
+
+    @Override
+    public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.drawRoundRect("+x+", "+y+", "+width+", "+height+","+arcWidth+", "+arcHeight+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+        }
+
+        draw(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
+    }
+
+
+
+
+
+    /***************************************************************************
+     *
+     *  String methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public void drawString(AttributedCharacterIterator iterator, float x, float y) {
+        GlyphVector gv = font.createGlyphVector(frc, iterator);
+        drawGlyphVector(gv, x, y);
+    }
+
+    @Override
+    public void drawString(AttributedCharacterIterator iterator, int x, int y) {
+        drawString(iterator, (float)x, (float)y);
+    }
+
+    @Override
+    public void drawString(String str, int x, int y) {
+        drawString(str, (float)x, (float)y);
+    }
+
+    @Override
+    public void drawString(String str, float x, float y) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.drawString("+str+", "+x+", "+y+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+        }
+
+        AffineTransform at = (AffineTransform)this.getTransform().clone();
+        AffineTransform fontTransform = font.getTransform();
+        at.concatenate(fontTransform);
+
+        double[] matrix = new double[6];
+        if (!at.isIdentity()){
+
+            int atType = at.getType();
+            at.getMatrix(matrix);
+
+            // TYPE_TRANSLATION
+            if (atType == AffineTransform.TYPE_TRANSLATION){
+                jtr.drawString(this, str,
+                        (float)(x+fontTransform.getTranslateX()),
+                        (float)(y+fontTransform.getTranslateY()));
+                return;
+            }
+            // TODO: we use slow type of drawing strings when Font object
+            // in Graphics has transforms, we just fill outlines. New textrenderer
+            // is to be implemented.
+            Shape sh = font.createGlyphVector(this.getFontRenderContext(), str).getOutline(x, y);
+            this.fill(sh);
+
+        } else {
+            jtr.drawString(this, str, x, y);
+        }
+
+    }
+
+    @Override
+    public void drawGlyphVector(GlyphVector gv, float x, float y) {
+
+        AffineTransform at = gv.getFont().getTransform();
+
+        double[] matrix = new double[6];
+        if ((at != null) && (!at.isIdentity())){
+
+            int atType = at.getType();
+            at.getMatrix(matrix);
+
+            // TYPE_TRANSLATION
+            if ((atType == AffineTransform.TYPE_TRANSLATION) &&
+                ((gv.getLayoutFlags() & GlyphVector.FLAG_HAS_TRANSFORMS) == 0)){
+                jtr.drawGlyphVector(this, gv, (int)(x+matrix[4]), (int)(y+matrix[5]));
+                return;
+            }
+        } else {
+            if (((gv.getLayoutFlags() & GlyphVector.FLAG_HAS_TRANSFORMS) == 0)){
+                jtr.drawGlyphVector(this, gv, x, y);
+                return;
+            }
+        }
+
+        // TODO: we use slow type of drawing strings when Font object
+        // in Graphics has transforms, we just fill outlines. New textrenderer
+        // is to be implemented.
+
+        Shape sh = gv.getOutline(x, y);
+        this.fill(sh);
+
+        }
+
+
+
+
+    /***************************************************************************
+     *
+     *  Fill methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public void fill(Shape s) {
+        s = transform.createTransformedShape(s);
+        MultiRectArea mra = jsr.rasterize(s, 0.5);
+        fillMultiRectArea(mra);
+    }
+
+    @Override
+    public void fillArc(int x, int y, int width, int height, int sa, int ea) {
+        fill(new Arc2D.Float(x, y, width, height, sa, ea, Arc2D.PIE));
+    }
+
+    @Override
+    public void fillOval(int x, int y, int width, int height) {
+        fill(new Ellipse2D.Float(x, y, width, height));
+    }
+
+    @Override
+    public void fillPolygon(int[] xpoints, int[] ypoints, int npoints) {
+        fill(new Polygon(xpoints, ypoints, npoints));
+    }
+
+    @Override
+    public void fillPolygon(Polygon polygon) {
+        fill(polygon);
+    }
+
+    @Override
+    public void fillRect(int x, int y, int width, int height) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.fillRect("+x+", "+y+", "+width+", "+height+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        }
+
+        fill(new Rectangle(x, y, width, height));
+    }
+
+    @Override
+    public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.fillRoundRect("+x+", "+y+", "+width+", "+height+","+arcWidth+", "+arcHeight+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+        }
+
+        fill(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
+    }
+
+
+
+
+    /***************************************************************************
+     *
+     *  Get methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public Color getBackground() {
+        return bgColor;
+    }
+
+    @Override
+    public Shape getClip() {
+        if (clip == null) {
+            return null;
+        }
+
+        MultiRectArea res = new MultiRectArea(clip);
+        res.translate(-Math.round((float)transform.getTranslateX()), -Math.round((float)transform.getTranslateY()));
+        return res;
+    }
+
+    @Override
+    public Rectangle getClipBounds() {
+        if (clip == null) {
+            return null;
+        }
+
+        Rectangle res = (Rectangle) clip.getBounds().clone();
+        res.translate(-Math.round((float)transform.getTranslateX()), -Math.round((float)transform.getTranslateY()));
+        return res;
+    }
+
+    @Override
+    public Color getColor() {
+        return fgColor;
+    }
+
+    @Override
+    public Composite getComposite() {
+        return composite;
+    }
+
+    @Override
+    public Font getFont() {
+        return font;
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public FontMetrics getFontMetrics(Font font) {
+        return Toolkit.getDefaultToolkit().getFontMetrics(font);
+    }
+
+    @Override
+    public FontRenderContext getFontRenderContext() {
+        return frc;
+    }
+
+    @Override
+    public Paint getPaint() {
+        return paint;
+    }
+
+    @Override
+    public Object getRenderingHint(RenderingHints.Key key) {
+        return hints.get(key);
+    }
+
+    @Override
+    public RenderingHints getRenderingHints() {
+        return hints;
+    }
+
+    @Override
+    public Stroke getStroke() {
+        return stroke;
+    }
+
+    @Override
+    public AffineTransform getTransform() {
+        return (AffineTransform)transform.clone();
+    }
+
+    @Override
+    public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
+        //TODO: Implement method....
+        return false;
+    }
+
+
+
+
+    /***************************************************************************
+     *
+     *  Transformation methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public void rotate(double theta) {
+        transform.rotate(theta);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void rotate(double theta, double x, double y) {
+        transform.rotate(theta, x, y);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void scale(double sx, double sy) {
+        transform.scale(sx, sy);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void shear(double shx, double shy) {
+        transform.shear(shx, shy);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void transform(AffineTransform at) {
+        transform.concatenate(at);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void translate(double tx, double ty) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.translate("+tx+", "+ty+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        transform.translate(tx, ty);
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void translate(int tx, int ty) {
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.translate("+tx+", "+ty+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+
+        transform.translate(tx, ty);
+        transform.getMatrix(matrix);
+    }
+
+
+
+
+    /***************************************************************************
+     *
+     *  Set methods
+     *
+     ***************************************************************************/
+
+    @Override
+    public void setBackground(Color color) {
+        bgColor = color;
+    }
+
+    @Override
+    public void setClip(int x, int y, int width, int height) {
+        setClip(new Rectangle(x, y, width, height));
+    }
+
+    @Override
+    public void setClip(Shape s) {
+        if (s == null) {
+            setTransformedClip(null);
+            if (debugOutput) {
+                System.err.println("CommonGraphics2D.setClip(null)"); //$NON-NLS-1$
+            }
+            return;
+        }
+
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.setClip("+s.getBounds()+")"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (s instanceof MultiRectArea) {
+            MultiRectArea nclip = new MultiRectArea((MultiRectArea)s);
+            nclip.translate(Math.round((float)transform.getTranslateX()), Math.round((float)transform.getTranslateY()));
+            setTransformedClip(nclip);
+        } else {
+            int type = transform.getType();
+            if(s instanceof Rectangle && (type & (AffineTransform.TYPE_IDENTITY |
+                AffineTransform.TYPE_TRANSLATION)) != 0){
+                    MultiRectArea nclip = new MultiRectArea((Rectangle)s);
+                    if(type == AffineTransform.TYPE_TRANSLATION){
+                        nclip.translate((int)transform.getTranslateX(), (int)transform.getTranslateY());
+                    }
+                    setTransformedClip(nclip);
+            } else {
+                s = transform.createTransformedShape(s);
+                setTransformedClip(jsr.rasterize(s, 0.5));
+            }
+        }
+    }
+
+    @Override
+    public void setColor(Color color) {
+        if (color != null) {
+            fgColor = color;
+            paint = color;
+        }
+    }
+
+    @Override
+    public void setComposite(Composite composite) {
+        this.composite = composite;
+    }
+
+    @Override
+    public void setFont(Font font) {
+        this.font = font;
+    }
+
+    @Override
+    public void setPaint(Paint paint) {
+        if (paint == null)
+            return;
+            
+        this.paint = paint;
+        if (paint instanceof Color) {
+            fgColor = (Color)paint;
+        }
+    }
+
+    @Override
+    public void setPaintMode() {
+        composite = AlphaComposite.SrcOver;
+    }
+
+    @Override
+    public void setRenderingHint(RenderingHints.Key key, Object value) {
+        hints.put(key, value);
+    }
+
+    @Override
+    public void setRenderingHints(Map<?,?> hints) {
+        this.hints.clear();
+        this.hints.putAll(hints);
+    }
+
+    @Override
+    public void setStroke(Stroke stroke) {
+        this.stroke = stroke;
+    }
+
+    @Override
+    public void setTransform(AffineTransform transform) {
+        this.transform = transform;
+
+        transform.getMatrix(matrix);
+    }
+
+    @Override
+    public void setXORMode(Color color) {
+        composite = new XORComposite(color);
+    }
+
+
+    // Protected methods
+    protected void setTransformedClip(MultiRectArea clip) {
+        this.clip = clip;
+    }
+
+    /**
+     * This method fills the given MultiRectArea with current paint.
+     * It calls fillMultiRectAreaColor and fillMultiRectAreaPaint 
+     * methods depending on the type of current paint.
+     * @param mra MultiRectArea to fill
+     */
+    protected void fillMultiRectArea(MultiRectArea mra) {
+        if (clip != null) {
+            mra.intersect(clip);
+        }
+
+        // Return if all stuff is clipped
+        if (mra.rect[0] < 5) {
+            return;
+        }
+
+        if (debugOutput) {
+            System.err.println("CommonGraphics2D.fillMultiRectArea("+mra+")"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        if (paint instanceof Color){
+            fillMultiRectAreaColor(mra);
+        }else{
+            fillMultiRectAreaPaint(mra);
+        }
+    }
+
+    /**
+     * This method fills the given MultiRectArea with solid color.
+     * @param mra MultiRectArea to fill
+     */
+    protected void fillMultiRectAreaColor(MultiRectArea mra) {
+        fillMultiRectAreaPaint(mra);
+    }
+
+    /**
+     * This method fills the given MultiRectArea with any paint.
+     * @param mra MultiRectArea to fill
+     */
+    protected void fillMultiRectAreaPaint(MultiRectArea mra) {
+        Rectangle rec = mra.getBounds();
+        int x = rec.x;
+        int y = rec.y;
+        int w = rec.width;
+        int h = rec.height;
+        if(w <= 0 || h <= 0) {
+            return;
+        }
+        PaintContext pc = paint.createContext(null, rec, rec, transform, hints);
+        Raster r = pc.getRaster(x, y, w, h);
+        WritableRaster wr;
+        if(r instanceof WritableRaster){
+            wr = (WritableRaster) r;
+        }else{
+            wr = r.createCompatibleWritableRaster();
+            wr.setRect(r);
+        }
+        Surface srcSurf = new ImageSurface(pc.getColorModel(), wr);
+        blitter.blit(0, 0, srcSurf, x, y, dstSurf, w, h,
+                composite, null, mra);
+        srcSurf.dispose();
+    }
+
+    /**
+     * Copies graphics class fields. 
+     * Used in create method
+     * 
+     * @param copy Graphics class to copy
+     */
+    protected void copyInternalFields(CommonGraphics2D copy) {
+        if (clip == null) {
+            copy.setTransformedClip(null);
+        } else {
+            copy.setTransformedClip(new MultiRectArea(clip));
+        }
+        copy.setBackground(bgColor);
+        copy.setColor(fgColor);
+        copy.setPaint(paint);
+        copy.setComposite(composite);
+        copy.setStroke(stroke);
+        copy.setFont(font);
+        copy.setTransform(new AffineTransform(transform));
+        //copy.origTransform = new AffineTransform(origTransform);
+        copy.origPoint = new Point(origPoint);
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/CommonGraphics2DFactory.java b/awt/org/apache/harmony/awt/gl/CommonGraphics2DFactory.java
new file mode 100644
index 0000000..27e3ef0
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/CommonGraphics2DFactory.java
@@ -0,0 +1,78 @@
+/*
+ *  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 Alexey A. Petrenko, Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.peer.FontPeer;
+
+import org.apache.harmony.awt.gl.font.FontMetricsImpl;
+import org.apache.harmony.awt.wtk.GraphicsFactory;
+
+/**
+ * Common GraphicsFactory implementation
+ *
+ */
+public abstract class CommonGraphics2DFactory implements GraphicsFactory {
+    
+    // static instance of CommonGraphics2DFactory
+    public static CommonGraphics2DFactory inst;
+
+    /**
+     * Returns FontMetrics object that keeps metrics of the specified font.
+     * 
+     * @param font specified Font
+     * @return FontMetrics object corresponding to the specified Font object
+     */
+    public FontMetrics getFontMetrics(Font font) {
+        FontMetrics fm;
+        for (FontMetrics element : cacheFM) {
+            fm = element;
+            if (fm == null){
+                break;
+            }
+
+            if (fm.getFont().equals(font)){
+                return fm;
+            }
+        }
+        fm = new FontMetricsImpl(font);
+
+        System.arraycopy(cacheFM, 0, cacheFM, 1, cacheFM.length -1);
+        cacheFM[0] = fm;
+
+        return fm;
+    }
+    // Font methods
+
+    public FontPeer getFontPeer(Font font) {
+        return getFontManager().getFontPeer(font.getName(), font.getStyle(), font.getSize());
+    }
+    
+    /**
+     * Embeds font from gile with specified path into the system. 
+     * 
+     * @param fontFilePath path to the font file 
+     * @return Font object that was created from the file.
+     */
+    public abstract Font embedFont(String fontFilePath);
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/CommonGraphicsEnvironment.java b/awt/org/apache/harmony/awt/gl/CommonGraphicsEnvironment.java
new file mode 100644
index 0000000..5c78e50
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/CommonGraphicsEnvironment.java
@@ -0,0 +1,67 @@
+/*
+ *  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 Alexey A. Petrenko, Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import org.apache.harmony.awt.gl.image.BufferedImageGraphics2D;
+
+/**
+ * Common GraphicsEnvironment implementation
+ *
+ */
+public abstract class CommonGraphicsEnvironment extends GraphicsEnvironment {
+
+    @Override
+    public Graphics2D createGraphics(BufferedImage bufferedImage) {
+        return new BufferedImageGraphics2D(bufferedImage);
+    }
+
+    @Override
+    public String[] getAvailableFontFamilyNames(Locale locale) {
+        Font[] fonts = getAllFonts();
+        ArrayList<String> familyNames = new ArrayList<String>();
+
+        for (Font element : fonts) {
+            String name = element.getFamily(locale);
+            if (!familyNames.contains(name)) {
+                familyNames.add(name);
+            }
+        }
+
+        return familyNames.toArray(new String[familyNames.size()]);
+    }
+
+    @Override
+    public Font[] getAllFonts() {
+        return CommonGraphics2DFactory.inst.getFontManager().getAllFonts();
+    }
+
+    @Override
+    public String[] getAvailableFontFamilyNames() {
+        return CommonGraphics2DFactory.inst.getFontManager().getAllFamilies();
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/Crossing.java b/awt/org/apache/harmony/awt/gl/Crossing.java
new file mode 100644
index 0000000..ae7fb0e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/Crossing.java
@@ -0,0 +1,889 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Shape;
+import java.awt.geom.PathIterator;
+
+public class Crossing {
+
+    /**
+     * Allowable tolerance for bounds comparison
+     */
+    static final double DELTA = 1E-5;
+    
+    /**
+     * If roots have distance less then <code>ROOT_DELTA</code> they are double
+     */
+    static final double ROOT_DELTA = 1E-10;
+    
+    /**
+     * Rectangle cross segment
+     */
+    public static final int CROSSING = 255;
+    
+    /**
+     * Unknown crossing result
+     */
+    static final int UNKNOWN = 254;
+
+    /**
+     * Solves quadratic equation
+     * @param eqn - the coefficients of the equation
+     * @param res - the roots of the equation
+     * @return a number of roots
+     */
+    public static int solveQuad(double eqn[], double res[]) {
+        double a = eqn[2];
+        double b = eqn[1];
+        double c = eqn[0];
+        int rc = 0;
+        if (a == 0.0) {
+            if (b == 0.0) {
+                return -1;
+            }
+            res[rc++] = -c / b;
+        } else {
+            double d = b * b - 4.0 * a * c;
+            // d < 0.0
+            if (d < 0.0) {
+                return 0;
+            }
+            d = Math.sqrt(d);
+            res[rc++] = (- b + d) / (a * 2.0);
+            // d != 0.0
+            if (d != 0.0) {
+                res[rc++] = (- b - d) / (a * 2.0);
+            }
+        }
+        return fixRoots(res, rc);
+    }
+
+    /**
+     * Solves cubic equation
+     * @param eqn - the coefficients of the equation
+     * @param res - the roots of the equation
+     * @return a number of roots
+     */
+    public static int solveCubic(double eqn[], double res[]) {
+        double d = eqn[3];
+        if (d == 0) {
+            return solveQuad(eqn, res);
+        }
+        double a = eqn[2] / d;
+        double b = eqn[1] / d;
+        double c = eqn[0] / d;
+        int rc = 0;
+
+        double Q = (a * a - 3.0 * b) / 9.0;
+        double R = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;
+        double Q3 = Q * Q * Q;
+        double R2 = R * R;
+        double n = - a / 3.0;
+
+        if (R2 < Q3) {
+            double t = Math.acos(R / Math.sqrt(Q3)) / 3.0;
+            double p = 2.0 * Math.PI / 3.0;
+            double m = -2.0 * Math.sqrt(Q);
+            res[rc++] = m * Math.cos(t) + n;
+            res[rc++] = m * Math.cos(t + p) + n;
+            res[rc++] = m * Math.cos(t - p) + n;
+        } else {
+//          Debug.println("R2 >= Q3 (" + R2 + "/" + Q3 + ")");
+            double A = Math.pow(Math.abs(R) + Math.sqrt(R2 - Q3), 1.0 / 3.0);
+            if (R > 0.0) {
+                A = -A;
+            }
+//          if (A == 0.0) {
+            if (-ROOT_DELTA < A && A < ROOT_DELTA) {
+                res[rc++] = n;
+            } else {
+                double B = Q / A;
+                res[rc++] = A + B + n;
+//              if (R2 == Q3) {
+                double delta = R2 - Q3;
+                if (-ROOT_DELTA < delta && delta < ROOT_DELTA) {
+                    res[rc++] = - (A + B) / 2.0 + n;
+                }
+            }
+
+        }
+        return fixRoots(res, rc);
+    }
+
+    /**
+     * Excludes double roots. Roots are double if they lies enough close with each other. 
+     * @param res - the roots 
+     * @param rc - the roots count
+     * @return new roots count
+     */
+    static int fixRoots(double res[], int rc) {
+        int tc = 0;
+        for(int i = 0; i < rc; i++) {
+            out: {
+                for(int j = i + 1; j < rc; j++) {
+                    if (isZero(res[i] - res[j])) {
+                        break out;
+                    }
+                }
+                res[tc++] = res[i];
+            }
+        }
+        return tc;
+    }
+
+    /**
+     * QuadCurve class provides basic functionality to find curve crossing and calculating bounds
+     */
+    public static class QuadCurve {
+
+        double ax, ay, bx, by;
+        double Ax, Ay, Bx, By;
+
+        public QuadCurve(double x1, double y1, double cx, double cy, double x2, double y2) {
+            ax = x2 - x1;
+            ay = y2 - y1;
+            bx = cx - x1;
+            by = cy - y1;
+
+            Bx = bx + bx;   // Bx = 2.0 * bx
+            Ax = ax - Bx;   // Ax = ax - 2.0 * bx
+
+            By = by + by;   // By = 2.0 * by
+            Ay = ay - By;   // Ay = ay - 2.0 * by
+        }
+
+        int cross(double res[], int rc, double py1, double py2) {
+            int cross = 0;
+
+            for (int i = 0; i < rc; i++) {
+                double t = res[i];
+
+                // CURVE-OUTSIDE
+                if (t < -DELTA || t > 1 + DELTA) {
+                    continue;
+                }
+                // CURVE-START
+                if (t < DELTA) {
+                    if (py1 < 0.0 && (bx != 0.0 ? bx : ax - bx) < 0.0) {
+                        cross--;
+                    }
+                    continue;
+                }
+                // CURVE-END
+                if (t > 1 - DELTA) {
+                    if (py1 < ay && (ax != bx ? ax - bx : bx) > 0.0) {
+                        cross++;
+                    }
+                    continue;
+                }
+                // CURVE-INSIDE
+                double ry = t * (t * Ay + By);
+                // ry = t * t * Ay + t * By
+                if (ry > py2) {
+                    double rxt = t * Ax + bx;
+                    // rxt = 2.0 * t * Ax + Bx = 2.0 * t * Ax + 2.0 * bx
+                    if (rxt > -DELTA && rxt < DELTA) {
+                        continue;
+                    }
+                    cross += rxt > 0.0 ? 1 : -1;
+                }
+            } // for
+
+            return cross;
+        }
+
+        int solvePoint(double res[], double px) {
+            double eqn[] = {-px, Bx, Ax};
+            return solveQuad(eqn, res);
+        }
+
+        int solveExtrem(double res[]) {
+            int rc = 0;
+            if (Ax != 0.0) {
+                res[rc++] = - Bx / (Ax + Ax);
+            }
+            if (Ay != 0.0) {
+                res[rc++] = - By / (Ay + Ay);
+            }
+            return rc;
+        }
+
+        int addBound(double bound[], int bc, double res[], int rc, double minX, double maxX, boolean changeId, int id) {
+            for(int i = 0; i < rc; i++) {
+                double t = res[i];
+                if (t > -DELTA && t < 1 + DELTA) {
+                    double rx = t * (t * Ax + Bx);
+                    if (minX <= rx && rx <= maxX) {
+                        bound[bc++] = t;
+                        bound[bc++] = rx;
+                        bound[bc++] = t * (t * Ay + By);
+                        bound[bc++] = id;
+                        if (changeId) {
+                            id++;
+                        }
+                    }
+                }
+            }
+            return bc;
+        }
+
+    }
+
+    /**
+     * CubicCurve class provides basic functionality to find curve crossing and calculating bounds
+     */
+    public static class CubicCurve {
+
+        double ax, ay, bx, by, cx, cy;
+        double Ax, Ay, Bx, By, Cx, Cy;
+        double Ax3, Bx2;
+
+        public CubicCurve(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2) {
+            ax = x2 - x1;
+            ay = y2 - y1;
+            bx = cx1 - x1;
+            by = cy1 - y1;
+            cx = cx2 - x1;
+            cy = cy2 - y1;
+
+            Cx = bx + bx + bx;           // Cx = 3.0 * bx
+            Bx = cx + cx + cx - Cx - Cx; // Bx = 3.0 * cx - 6.0 * bx
+            Ax = ax - Bx - Cx;           // Ax = ax - 3.0 * cx + 3.0 * bx
+
+            Cy = by + by + by;           // Cy = 3.0 * by
+            By = cy + cy + cy - Cy - Cy; // By = 3.0 * cy - 6.0 * by
+            Ay = ay - By - Cy;           // Ay = ay - 3.0 * cy + 3.0 * by
+
+            Ax3 = Ax + Ax + Ax;
+            Bx2 = Bx + Bx;
+        }
+
+        int cross(double res[], int rc, double py1, double py2) {
+            int cross = 0;
+            for (int i = 0; i < rc; i++) {
+                double t = res[i];
+
+                // CURVE-OUTSIDE
+                if (t < -DELTA || t > 1 + DELTA) {
+                    continue;
+                }
+                // CURVE-START
+                if (t < DELTA) {
+                    if (py1 < 0.0 && (bx != 0.0 ? bx : (cx != bx ? cx - bx : ax - cx)) < 0.0) {
+                        cross--;
+                    }
+                    continue;
+                }
+                // CURVE-END
+                if (t > 1 - DELTA) {
+                    if (py1 < ay && (ax != cx ? ax - cx : (cx != bx ? cx - bx : bx)) > 0.0) {
+                        cross++;
+                    }
+                    continue;
+                }
+                // CURVE-INSIDE
+                double ry = t * (t * (t * Ay + By) + Cy);
+                // ry = t * t * t * Ay + t * t * By + t * Cy
+                if (ry > py2) {
+                    double rxt = t * (t * Ax3 + Bx2) + Cx;
+                    // rxt = 3.0 * t * t * Ax + 2.0 * t * Bx + Cx
+                    if (rxt > -DELTA && rxt < DELTA) {
+                        rxt = t * (Ax3 + Ax3) + Bx2;
+                        // rxt = 6.0 * t * Ax + 2.0 * Bx
+                        if (rxt < -DELTA || rxt > DELTA) {
+                            // Inflection point
+                            continue;
+                        }
+                        rxt = ax;
+                    }
+                    cross += rxt > 0.0 ? 1 : -1;
+                }
+            } //for
+
+            return cross;
+        }
+
+        int solvePoint(double res[], double px) {
+            double eqn[] = {-px, Cx, Bx, Ax};
+            return solveCubic(eqn, res);
+        }
+
+        int solveExtremX(double res[]) {
+            double eqn[] = {Cx, Bx2, Ax3};
+            return solveQuad(eqn, res);
+        }
+
+        int solveExtremY(double res[]) {
+            double eqn[] = {Cy, By + By, Ay + Ay + Ay};
+            return solveQuad(eqn, res);
+        }
+
+        int addBound(double bound[], int bc, double res[], int rc, double minX, double maxX, boolean changeId, int id) {
+            for(int i = 0; i < rc; i++) {
+                double t = res[i];
+                if (t > -DELTA && t < 1 + DELTA) {
+                    double rx = t * (t * (t * Ax + Bx) + Cx);
+                    if (minX <= rx && rx <= maxX) {
+                        bound[bc++] = t;
+                        bound[bc++] = rx;
+                        bound[bc++] = t * (t * (t * Ay + By) + Cy);
+                        bound[bc++] = id;
+                        if (changeId) {
+                            id++;
+                        }
+                    }
+                }
+            }
+            return bc;
+        }
+
+    }
+
+    /**
+     * Returns how many times ray from point (x,y) cross line.
+     */
+    public static int crossLine(double x1, double y1, double x2, double y2, double x, double y) {
+
+        // LEFT/RIGHT/UP/EMPTY
+        if ((x < x1 && x < x2) ||
+            (x > x1 && x > x2) ||
+            (y > y1 && y > y2) ||
+            (x1 == x2))
+        {
+            return 0;
+        }
+
+        // DOWN
+        if (y < y1 && y < y2) {
+        } else {
+            // INSIDE
+            if ((y2 - y1) * (x - x1) / (x2 - x1) <= y - y1) {
+                // INSIDE-UP
+                return 0;
+            }
+        }
+
+        // START
+        if (x == x1) {
+            return x1 < x2 ? 0 : -1;
+        }
+
+        // END
+        if (x == x2) {
+            return x1 < x2 ? 1 : 0;
+        }
+
+        // INSIDE-DOWN
+        return x1 < x2 ? 1 : -1;
+    }
+
+    /**
+     * Returns how many times ray from point (x,y) cross quard curve
+     */
+    public static int crossQuad(double x1, double y1, double cx, double cy, double x2, double y2, double x, double y) {
+
+        // LEFT/RIGHT/UP/EMPTY
+        if ((x < x1 && x < cx && x < x2) ||
+            (x > x1 && x > cx && x > x2) ||
+            (y > y1 && y > cy && y > y2) ||
+            (x1 == cx && cx == x2))
+        {
+            return 0;
+        }
+
+        // DOWN
+        if (y < y1 && y < cy && y < y2 && x != x1 && x != x2) {
+            if (x1 < x2) {
+                return x1 < x && x < x2 ? 1 : 0;
+            }
+            return x2 < x && x < x1 ? -1 : 0;
+        }
+
+        // INSIDE
+        QuadCurve c = new QuadCurve(x1, y1, cx, cy, x2, y2);
+        double px = x - x1;
+        double py = y - y1;
+        double res[] = new double[3];
+        int rc = c.solvePoint(res, px);
+
+        return c.cross(res, rc, py, py);
+    }
+
+    /**
+     * Returns how many times ray from point (x,y) cross cubic curve
+     */
+    public static int crossCubic(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2, double x, double y) {
+
+        // LEFT/RIGHT/UP/EMPTY
+        if ((x < x1 && x < cx1 && x < cx2 && x < x2) ||
+            (x > x1 && x > cx1 && x > cx2 && x > x2) ||
+            (y > y1 && y > cy1 && y > cy2 && y > y2) ||
+            (x1 == cx1 && cx1 == cx2 && cx2 == x2))
+        {
+            return 0;
+        }
+
+        // DOWN
+        if (y < y1 && y < cy1 && y < cy2 && y < y2 && x != x1 && x != x2) {
+            if (x1 < x2) {
+                return x1 < x && x < x2 ? 1 : 0;
+            }
+            return x2 < x && x < x1 ? -1 : 0;
+        }
+
+        // INSIDE
+        CubicCurve c = new CubicCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
+        double px = x - x1;
+        double py = y - y1;
+        double res[] = new double[3];
+        int rc = c.solvePoint(res, px);
+        return c.cross(res, rc, py, py);
+    }
+
+    /**
+     * Returns how many times ray from point (x,y) cross path
+     */
+    public static int crossPath(PathIterator p, double x, double y) {
+        int cross = 0;
+        double mx, my, cx, cy;
+        mx = my = cx = cy = 0.0;
+        double coords[] = new double[6];
+
+        while (!p.isDone()) {
+            switch (p.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (cx != mx || cy != my) {
+                    cross += crossLine(cx, cy, mx, my, x, y);
+                }
+                mx = cx = coords[0];
+                my = cy = coords[1];
+                break;
+            case PathIterator.SEG_LINETO:
+                cross += crossLine(cx, cy, cx = coords[0], cy = coords[1], x, y);
+                break;
+            case PathIterator.SEG_QUADTO:
+                cross += crossQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], x, y);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                cross += crossCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], x, y);
+                break;
+            case PathIterator.SEG_CLOSE:
+                if (cy != my || cx != mx) {
+                    cross += crossLine(cx, cy, cx = mx, cy = my, x, y);
+                }
+                break;
+            }
+            p.next();
+        }
+        if (cy != my) {
+            cross += crossLine(cx, cy, mx, my, x, y);
+        }
+        return cross;
+    }
+
+    /**
+     * Returns how many times ray from point (x,y) cross shape
+     */
+    public static int crossShape(Shape s, double x, double y) {
+        if (!s.getBounds2D().contains(x, y)) {
+            return 0;
+        }
+        return crossPath(s.getPathIterator(null), x, y);
+    }
+
+    /**
+     * Returns true if value enough small
+     */
+    public static boolean isZero(double val) {
+        return -DELTA < val && val < DELTA;
+    }
+
+    /**
+     * Sort bound array
+     */
+    static void sortBound(double bound[], int bc) {
+        for(int i = 0; i < bc - 4; i += 4) {
+            int k = i;
+            for(int j = i + 4; j < bc; j += 4) {
+                if (bound[k] > bound[j]) {
+                    k = j;
+                }
+            }
+            if (k != i) {
+                double tmp = bound[i];
+                bound[i] = bound[k];
+                bound[k] = tmp;
+                tmp = bound[i + 1];
+                bound[i + 1] = bound[k + 1];
+                bound[k + 1] = tmp;
+                tmp = bound[i + 2];
+                bound[i + 2] = bound[k + 2];
+                bound[k + 2] = tmp;
+                tmp = bound[i + 3];
+                bound[i + 3] = bound[k + 3];
+                bound[k + 3] = tmp;
+            }
+        }
+    }
+    
+    /**
+     * Returns are bounds intersect or not intersect rectangle 
+     */
+    static int crossBound(double bound[], int bc, double py1, double py2) {
+
+        // LEFT/RIGHT
+        if (bc == 0) {
+            return 0;
+        }
+
+        // Check Y coordinate
+        int up = 0;
+        int down = 0;
+        for(int i = 2; i < bc; i += 4) {
+            if (bound[i] < py1) {
+                up++;
+                continue;
+            }
+            if (bound[i] > py2) {
+                down++;
+                continue;
+            }
+            return CROSSING;
+        }
+
+        // UP
+        if (down == 0) {
+            return 0;
+        }
+
+        if (up != 0) {
+            // bc >= 2
+            sortBound(bound, bc);
+            boolean sign = bound[2] > py2;
+            for(int i = 6; i < bc; i += 4) {
+                boolean sign2 = bound[i] > py2;
+                if (sign != sign2 && bound[i + 1] != bound[i - 3]) {
+                    return CROSSING;
+                }
+                sign = sign2;
+            }
+        }
+        return UNKNOWN;
+    }
+
+    /**
+     * Returns how many times rectangle stripe cross line or the are intersect
+     */
+    public static int intersectLine(double x1, double y1, double x2, double y2, double rx1, double ry1, double rx2, double ry2) {
+
+        // LEFT/RIGHT/UP
+        if ((rx2 < x1 && rx2 < x2) ||
+            (rx1 > x1 && rx1 > x2) ||
+            (ry1 > y1 && ry1 > y2))
+        {
+            return 0;
+        }
+
+        // DOWN
+        if (ry2 < y1 && ry2 < y2) {
+        } else {
+
+            // INSIDE
+            if (x1 == x2) {
+                return CROSSING;
+            }
+
+            // Build bound
+            double bx1, bx2;
+            if (x1 < x2) {
+                bx1 = x1 < rx1 ? rx1 : x1;
+                bx2 = x2 < rx2 ? x2 : rx2;
+            } else {
+                bx1 = x2 < rx1 ? rx1 : x2;
+                bx2 = x1 < rx2 ? x1 : rx2;
+            }
+            double k = (y2 - y1) / (x2 - x1);
+            double by1 = k * (bx1 - x1) + y1;
+            double by2 = k * (bx2 - x1) + y1;
+
+            // BOUND-UP
+            if (by1 < ry1 && by2 < ry1) {
+                return 0;
+            }
+
+            // BOUND-DOWN
+            if (by1 > ry2 && by2 > ry2) {
+            } else {
+                return CROSSING;
+            }
+        }
+
+        // EMPTY
+        if (x1 == x2) {
+            return 0;
+        }
+
+        // CURVE-START
+        if (rx1 == x1) {
+            return x1 < x2 ? 0 : -1;
+        }
+
+        // CURVE-END
+        if (rx1 == x2) {
+            return x1 < x2 ? 1 : 0;
+        }
+
+        if (x1 < x2) {
+            return x1 < rx1 && rx1 < x2 ? 1 : 0;
+        }
+        return x2 < rx1 && rx1 < x1 ? -1 : 0;
+
+    }
+
+    /**
+     * Returns how many times rectangle stripe cross quad curve or the are intersect
+     */
+    public static int intersectQuad(double x1, double y1, double cx, double cy, double x2, double y2, double rx1, double ry1, double rx2, double ry2) {
+
+        // LEFT/RIGHT/UP ------------------------------------------------------
+        if ((rx2 < x1 && rx2 < cx && rx2 < x2) ||
+            (rx1 > x1 && rx1 > cx && rx1 > x2) ||
+            (ry1 > y1 && ry1 > cy && ry1 > y2))
+        {
+            return 0;
+        }
+
+        // DOWN ---------------------------------------------------------------
+        if (ry2 < y1 && ry2 < cy && ry2 < y2 && rx1 != x1 && rx1 != x2) {
+            if (x1 < x2) {
+                return x1 < rx1 && rx1 < x2 ? 1 : 0;
+            }
+            return x2 < rx1 && rx1 < x1 ? -1 : 0;
+        }
+
+        // INSIDE -------------------------------------------------------------
+        QuadCurve c = new QuadCurve(x1, y1, cx, cy, x2, y2);
+        double px1 = rx1 - x1;
+        double py1 = ry1 - y1;
+        double px2 = rx2 - x1;
+        double py2 = ry2 - y1;
+
+        double res1[] = new double[3];
+        double res2[] = new double[3];
+        int rc1 = c.solvePoint(res1, px1);
+        int rc2 = c.solvePoint(res2, px2);
+
+        // INSIDE-LEFT/RIGHT
+        if (rc1 == 0 && rc2 == 0) {
+            return 0;
+        }
+
+        // Build bound --------------------------------------------------------
+        double minX = px1 - DELTA;
+        double maxX = px2 + DELTA;
+        double bound[] = new double[28];
+        int bc = 0;
+        // Add roots
+        bc = c.addBound(bound, bc, res1, rc1, minX, maxX, false, 0);
+        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, false, 1);
+        // Add extremal points`
+        rc2 = c.solveExtrem(res2);
+        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 2);
+        // Add start and end
+        if (rx1 < x1 && x1 < rx2) {
+            bound[bc++] = 0.0;
+            bound[bc++] = 0.0;
+            bound[bc++] = 0.0;
+            bound[bc++] = 4;
+        }
+        if (rx1 < x2 && x2 < rx2) {
+            bound[bc++] = 1.0;
+            bound[bc++] = c.ax;
+            bound[bc++] = c.ay;
+            bound[bc++] = 5;
+        }
+        // End build bound ----------------------------------------------------
+
+        int cross = crossBound(bound, bc, py1, py2);
+        if (cross != UNKNOWN) {
+            return cross;
+        }
+        return c.cross(res1, rc1, py1, py2);
+    }
+
+    /**
+     * Returns how many times rectangle stripe cross cubic curve or the are intersect
+     */
+    public static int intersectCubic(double x1, double y1, double cx1, double cy1, double cx2, double cy2, double x2, double y2, double rx1, double ry1, double rx2, double ry2) {
+
+        // LEFT/RIGHT/UP
+        if ((rx2 < x1 && rx2 < cx1 && rx2 < cx2 && rx2 < x2) ||
+            (rx1 > x1 && rx1 > cx1 && rx1 > cx2 && rx1 > x2) ||
+            (ry1 > y1 && ry1 > cy1 && ry1 > cy2 && ry1 > y2))
+        {
+            return 0;
+        }
+
+        // DOWN
+        if (ry2 < y1 && ry2 < cy1 && ry2 < cy2 && ry2 < y2 && rx1 != x1 && rx1 != x2) {
+            if (x1 < x2) {
+                return x1 < rx1 && rx1 < x2 ? 1 : 0;
+            }
+            return x2 < rx1 && rx1 < x1 ? -1 : 0;
+        }
+
+        // INSIDE
+        CubicCurve c = new CubicCurve(x1, y1, cx1, cy1, cx2, cy2, x2, y2);
+        double px1 = rx1 - x1;
+        double py1 = ry1 - y1;
+        double px2 = rx2 - x1;
+        double py2 = ry2 - y1;
+
+        double res1[] = new double[3];
+        double res2[] = new double[3];
+        int rc1 = c.solvePoint(res1, px1);
+        int rc2 = c.solvePoint(res2, px2);
+
+        // LEFT/RIGHT
+        if (rc1 == 0 && rc2 == 0) {
+            return 0;
+        }
+
+        double minX = px1 - DELTA;
+        double maxX = px2 + DELTA;
+
+        // Build bound --------------------------------------------------------
+        double bound[] = new double[40];
+        int bc = 0;
+        // Add roots
+        bc = c.addBound(bound, bc, res1, rc1, minX, maxX, false, 0);
+        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, false, 1);
+        // Add extrimal points
+        rc2 = c.solveExtremX(res2);
+        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 2);
+        rc2 = c.solveExtremY(res2);
+        bc = c.addBound(bound, bc, res2, rc2, minX, maxX, true, 4);
+        // Add start and end
+        if (rx1 < x1 && x1 < rx2) {
+            bound[bc++] = 0.0;
+            bound[bc++] = 0.0;
+            bound[bc++] = 0.0;
+            bound[bc++] = 6;
+        }
+        if (rx1 < x2 && x2 < rx2) {
+            bound[bc++] = 1.0;
+            bound[bc++] = c.ax;
+            bound[bc++] = c.ay;
+            bound[bc++] = 7;
+        }
+        // End build bound ----------------------------------------------------
+
+        int cross = crossBound(bound, bc, py1, py2);
+        if (cross != UNKNOWN) {
+            return cross;
+        }
+        return c.cross(res1, rc1, py1, py2);
+    }
+
+    /**
+     * Returns how many times rectangle stripe cross path or the are intersect
+     */
+    public static int intersectPath(PathIterator p, double x, double y, double w, double h) {
+
+        int cross = 0;
+        int count;
+        double mx, my, cx, cy;
+        mx = my = cx = cy = 0.0;
+        double coords[] = new double[6];
+
+        double rx1 = x;
+        double ry1 = y;
+        double rx2 = x + w;
+        double ry2 = y + h;
+
+        while (!p.isDone()) {
+            count = 0;
+            switch (p.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (cx != mx || cy != my) {
+                    count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
+                }
+                mx = cx = coords[0];
+                my = cy = coords[1];
+                break;
+            case PathIterator.SEG_LINETO:
+                count = intersectLine(cx, cy, cx = coords[0], cy = coords[1], rx1, ry1, rx2, ry2);
+                break;
+            case PathIterator.SEG_QUADTO:
+                count = intersectQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], rx1, ry1, rx2, ry2);
+                break;
+            case PathIterator.SEG_CUBICTO:
+                count = intersectCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], rx1, ry1, rx2, ry2);
+                break;
+            case PathIterator.SEG_CLOSE:
+                if (cy != my || cx != mx) {
+                    count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
+                }
+                cx = mx;
+                cy = my;
+                break;
+            }
+            if (count == CROSSING) {
+                return CROSSING;
+            }
+            cross += count;
+            p.next();
+        }
+        if (cy != my) {
+            count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
+            if (count == CROSSING) {
+                return CROSSING;
+            }
+            cross += count;
+        }
+        return cross;
+    }
+
+    /**
+     * Returns how many times rectangle stripe cross shape or the are intersect
+     */
+    public static int intersectShape(Shape s, double x, double y, double w, double h) {
+        if (!s.getBounds2D().intersects(x, y, w, h)) {
+            return 0;
+        }
+        return intersectPath(s.getPathIterator(null), x, y, w, h);
+    }
+
+    /**
+     * Returns true if cross count correspond inside location for non zero path rule
+     */
+    public static boolean isInsideNonZero(int cross) {
+        return cross != 0;
+    }
+
+    /**
+     * Returns true if cross count correspond inside location for even-odd path rule
+     */
+    public static boolean isInsideEvenOdd(int cross) {
+        return (cross & 1) != 0;
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/GLVolatileImage.java b/awt/org/apache/harmony/awt/gl/GLVolatileImage.java
new file mode 100644
index 0000000..177be23
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/GLVolatileImage.java
@@ -0,0 +1,30 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.image.*;
+
+import org.apache.harmony.awt.gl.Surface;
+
+public abstract class GLVolatileImage extends VolatileImage {
+
+    public abstract Surface getImageSurface();
+}
diff --git a/awt/org/apache/harmony/awt/gl/ICompositeContext.java b/awt/org/apache/harmony/awt/gl/ICompositeContext.java
new file mode 100644
index 0000000..fc5631f
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/ICompositeContext.java
@@ -0,0 +1,90 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.gl.render.NativeImageBlitter;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * This class represent implementation of the CompositeContext interface
+ */
+public class ICompositeContext implements CompositeContext {
+    Composite composite;
+    ColorModel srcCM, dstCM;
+    ImageSurface srcSurf, dstSurf;
+
+    public ICompositeContext(Composite comp, ColorModel src, ColorModel dst){
+        composite = comp;
+        srcCM = src;
+        dstCM = dst;
+    }
+
+    public void dispose() {
+        srcSurf.dispose();
+        dstSurf.dispose();
+    }
+
+    public void compose(Raster srcIn, Raster dstIn, WritableRaster dstOut) {
+
+        if(!srcCM.isCompatibleRaster(srcIn)) {
+            // awt.48=The srcIn raster is incompatible with src ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.48")); //$NON-NLS-1$
+        }
+
+        if(!dstCM.isCompatibleRaster(dstIn)) {
+            // awt.49=The dstIn raster is incompatible with dst ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.49")); //$NON-NLS-1$
+        }
+
+        if(dstIn != dstOut){
+            if(!dstCM.isCompatibleRaster(dstOut)) {
+                // awt.4A=The dstOut raster is incompatible with dst ColorModel
+                throw new IllegalArgumentException(Messages.getString("awt.4A")); //$NON-NLS-1$
+            }
+            dstOut.setDataElements(0, 0, dstIn);
+        }
+        WritableRaster src;
+        if(srcIn instanceof WritableRaster){
+            src = (WritableRaster) srcIn;
+        }else{
+            src = srcIn.createCompatibleWritableRaster();
+            src.setDataElements(0, 0, srcIn);
+        }
+        srcSurf = new ImageSurface(srcCM, src);
+        dstSurf = new ImageSurface(dstCM, dstOut);
+
+        int w = Math.min(srcIn.getWidth(), dstOut.getWidth());
+        int h = Math.min(srcIn.getHeight(), dstOut.getHeight());
+
+        NativeImageBlitter.getInstance().blit(0, 0, srcSurf, 0, 0, dstSurf,
+                w, h, composite, null, null);
+
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/ImageSurface.java b/awt/org/apache/harmony/awt/gl/ImageSurface.java
new file mode 100644
index 0000000..6368dd8
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/ImageSurface.java
@@ -0,0 +1,323 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 10.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.color.ColorSpace;
+import java.awt.image.BandedSampleModel;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.PixelInterleavedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+import org.apache.harmony.awt.gl.image.DataBufferListener;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * This class represent Surface for different types of Images (BufferedImage, 
+ * OffscreenImage and so on) 
+ */
+public class ImageSurface extends Surface implements DataBufferListener {
+
+    boolean nativeDrawable = true;
+    int surfaceType;
+    int csType;
+    ColorModel cm;
+    WritableRaster raster;
+    Object data;
+    
+    boolean needToRefresh = true;
+    boolean dataTaken = false;
+    
+    private long cachedDataPtr;       // Pointer for cached Image Data
+    private boolean alphaPre;         // Cached Image Data alpha premultiplied 
+
+    public ImageSurface(ColorModel cm, WritableRaster raster){
+        this(cm, raster, Surface.getType(cm, raster));
+    }
+
+    public ImageSurface(ColorModel cm, WritableRaster raster, int type){
+        if (!cm.isCompatibleRaster(raster)) {
+            // awt.4D=The raster is incompatible with this ColorModel
+            throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
+        }
+        this.cm = cm;
+        this.raster = raster;
+        surfaceType = type;
+
+        data = AwtImageBackdoorAccessor.getInstance().
+        getData(raster.getDataBuffer());
+        ColorSpace cs = cm.getColorSpace();
+        transparency = cm.getTransparency();
+        width = raster.getWidth();
+        height = raster.getHeight();
+
+        // For the moment we can build natively only images which have 
+        // sRGB, Linear_RGB, Linear_Gray Color Space and type different
+        // from BufferedImage.TYPE_CUSTOM
+        if(cs == LUTColorConverter.sRGB_CS){
+            csType = sRGB_CS;
+        }else if(cs == LUTColorConverter.LINEAR_RGB_CS){
+            csType = Linear_RGB_CS;
+        }else if(cs == LUTColorConverter.LINEAR_GRAY_CS){
+            csType = Linear_Gray_CS;
+        }else{
+            csType = Custom_CS;
+            nativeDrawable = false;
+        }
+
+        if(type == BufferedImage.TYPE_CUSTOM){
+            nativeDrawable = false;
+        }
+    }
+
+    @Override
+    public ColorModel getColorModel() {
+        return cm;
+    }
+
+    @Override
+    public WritableRaster getRaster() {
+        return raster;
+    }
+
+    @Override
+    public long getSurfaceDataPtr() {
+        if(surfaceDataPtr == 0L && nativeDrawable){
+            createSufaceStructure();
+        }
+        return surfaceDataPtr;
+    }
+
+    @Override
+    public Object getData(){
+        return data;
+    }
+
+    @Override
+    public boolean isNativeDrawable(){
+        return nativeDrawable;
+    }
+
+    @Override
+    public int getSurfaceType() {
+        return surfaceType;
+    }
+
+    /**
+     * Creates native Surface structure which used for native blitting
+     */
+    private void createSufaceStructure(){
+        int cmType = 0;
+        int numComponents = cm.getNumComponents();
+        boolean hasAlpha = cm.hasAlpha();
+        boolean isAlphaPre = cm.isAlphaPremultiplied();
+        int transparency = cm.getTransparency();
+        int bits[] = cm.getComponentSize();
+        int pixelStride = cm.getPixelSize();
+        int masks[] = null;
+        int colorMap[] = null;
+        int colorMapSize = 0;
+        int transpPixel = -1;
+        boolean isGrayPallete = false;
+        SampleModel sm = raster.getSampleModel();
+        int smType = 0;
+        int dataType = sm.getDataType();
+        int scanlineStride = 0;
+        int bankIndeces[] = null;
+        int bandOffsets[] = null;
+        int offset = raster.getDataBuffer().getOffset();
+
+        if(cm instanceof DirectColorModel){
+            cmType = DCM;
+            DirectColorModel dcm = (DirectColorModel) cm;
+            masks = dcm.getMasks();
+            smType = SPPSM;
+            SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+            scanlineStride = sppsm.getScanlineStride();
+
+        }else if(cm instanceof IndexColorModel){
+            cmType = ICM;
+            IndexColorModel icm = (IndexColorModel) cm;
+            colorMapSize = icm.getMapSize();
+            colorMap = new int[colorMapSize];
+            icm.getRGBs(colorMap);
+            transpPixel = icm.getTransparentPixel();
+            isGrayPallete = Surface.isGrayPallete(icm);
+
+            if(sm instanceof MultiPixelPackedSampleModel){
+                smType = MPPSM;
+                MultiPixelPackedSampleModel mppsm =
+                    (MultiPixelPackedSampleModel) sm;
+                scanlineStride = mppsm.getScanlineStride();
+            }else if(sm instanceof ComponentSampleModel){
+                smType = CSM;
+                ComponentSampleModel csm =
+                    (ComponentSampleModel) sm;
+                scanlineStride = csm.getScanlineStride();
+            }else{
+                // awt.4D=The raster is incompatible with this ColorModel
+                throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
+            }
+
+        }else if(cm instanceof ComponentColorModel){
+            cmType = CCM;
+            if(sm instanceof ComponentSampleModel){
+                ComponentSampleModel csm = (ComponentSampleModel) sm;
+                scanlineStride = csm.getScanlineStride();
+                bankIndeces = csm.getBankIndices();
+                bandOffsets = csm.getBandOffsets();
+                if(sm instanceof PixelInterleavedSampleModel){
+                    smType = PISM;
+                }else if(sm instanceof BandedSampleModel){
+                    smType = BSM;
+                }else{
+                    smType = CSM;
+                }
+            }else{
+                // awt.4D=The raster is incompatible with this ColorModel
+                throw new IllegalArgumentException(Messages.getString("awt.4D")); //$NON-NLS-1$
+            }
+
+        }else{
+            surfaceDataPtr = 0L;
+            return;
+        }
+        surfaceDataPtr = createSurfStruct(surfaceType, width, height, cmType, csType, smType, dataType,
+                numComponents, pixelStride, scanlineStride, bits, masks, colorMapSize,
+                colorMap, transpPixel, isGrayPallete, bankIndeces, bandOffsets,
+                offset, hasAlpha, isAlphaPre, transparency);
+    }
+
+    @Override
+    public void dispose() {
+        if(surfaceDataPtr != 0L){
+            dispose(surfaceDataPtr);
+            surfaceDataPtr = 0L;
+        }
+    }
+    
+    public long getCachedData(boolean alphaPre){
+        if(nativeDrawable){
+            if(cachedDataPtr == 0L || needToRefresh || this.alphaPre != alphaPre){
+                cachedDataPtr = updateCache(getSurfaceDataPtr(), data, alphaPre);
+                this.alphaPre = alphaPre;
+                validate(); 
+            }
+        }
+        return cachedDataPtr;
+    }
+
+    private native long createSurfStruct(int surfaceType, int width, int height, 
+            int cmType, int csType, int smType, int dataType,
+            int numComponents, int pixelStride, int scanlineStride,
+            int bits[], int masks[], int colorMapSize, int colorMap[],
+            int transpPixel, boolean isGrayPalette, int bankIndeces[], 
+            int bandOffsets[], int offset, boolean hasAlpha, boolean isAlphaPre,
+            int transparency);
+
+    private native void dispose(long structPtr);
+
+    private native void setImageSize(long structPtr, int width, int height);
+
+    private native long updateCache(long structPtr, Object data, boolean alphaPre);
+    
+    /**
+     * Supposes that new raster is compatible with an old one
+     * @param r
+     */
+    public void setRaster(WritableRaster r) {
+        raster = r;
+        data = AwtImageBackdoorAccessor.getInstance().getData(r.getDataBuffer());
+        if (surfaceDataPtr != 0) {
+            setImageSize(surfaceDataPtr, r.getWidth(), r.getHeight());
+        }
+        this.width = r.getWidth();
+        this.height = r.getHeight();
+    }
+
+    @Override
+    public long lock() {
+        // TODO
+        return 0;
+    }
+
+    @Override
+    public void unlock() {
+        //TODO
+    }
+
+    @Override
+    public Surface getImageSurface() {
+        return this;
+    }
+
+    public void dataChanged() {
+        needToRefresh = true;
+        clearValidCaches();
+    }
+
+    public void dataTaken() {
+        dataTaken = true;
+        needToRefresh = true;
+        clearValidCaches();
+    }
+    
+    public void dataReleased(){
+        dataTaken = false;
+        needToRefresh = true;
+        clearValidCaches();
+    }
+    
+    @Override
+    public void invalidate(){
+        needToRefresh = true;
+        clearValidCaches();
+    }
+    
+    @Override
+    public void validate(){
+        if(!needToRefresh) {
+            return;
+        }
+        if(!dataTaken){
+            needToRefresh = false;
+            AwtImageBackdoorAccessor ba = AwtImageBackdoorAccessor.getInstance();
+            ba.validate(raster.getDataBuffer());
+        }
+        
+    }
+    
+    @Override
+    public boolean invalidated(){
+        return needToRefresh;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/MultiRectArea.java b/awt/org/apache/harmony/awt/gl/MultiRectArea.java
new file mode 100644
index 0000000..c4267f3
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/MultiRectArea.java
@@ -0,0 +1,836 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class MultiRectArea implements Shape {
+
+    /**
+     * If CHECK is true validation check active
+     */
+    private static final boolean CHECK = false;
+
+    boolean sorted = true;
+    
+    /**
+     * Rectangle buffer
+     */
+    public int[] rect;
+    
+    /**
+     * Bounding box
+     */
+    Rectangle bounds;
+    
+    /**
+     * Result rectangle array
+     */
+    Rectangle[] rectangles;
+
+    /**
+     * LineCash provides creating MultiRectArea line by line. Used in JavaShapeRasterizer.
+     */
+    public static class LineCash extends MultiRectArea {
+
+        int lineY;
+        int bottomCount;
+        int[] bottom;
+
+        public LineCash(int size) {
+            super();
+            bottom = new int[size];
+            bottomCount = 0;
+        }
+
+        public void setLine(int y) {
+            lineY = y;
+        }
+
+        public void skipLine() {
+            lineY++;
+            bottomCount = 0;
+        }
+
+        public void addLine(int[] points, int pointCount) {
+            int bottomIndex = 0;
+            int pointIndex = 0;
+            int rectIndex = 0;
+            int pointX1 = 0;
+            int pointX2 = 0;
+            int bottomX1 = 0;
+            int bottomX2 = 0;
+            boolean appendRect = false;
+            boolean deleteRect = false;
+            int lastCount = bottomCount;
+
+            while (bottomIndex < lastCount || pointIndex < pointCount) {
+
+                appendRect = false;
+                deleteRect = false;
+
+                if (bottomIndex < lastCount) {
+                    rectIndex = bottom[bottomIndex];
+                    bottomX1 = rect[rectIndex];
+                    bottomX2 = rect[rectIndex + 2];
+                } else {
+                    appendRect = true;
+                }
+
+                if (pointIndex < pointCount) {
+                    pointX1 = points[pointIndex];
+                    pointX2 = points[pointIndex + 1];
+                } else {
+                    deleteRect = true;
+                }
+
+                if (!deleteRect && !appendRect) {
+                    if (pointX1 == bottomX1 && pointX2 == bottomX2) {
+                        rect[rectIndex + 3] = rect[rectIndex + 3] + 1;
+                        pointIndex += 2;
+                        bottomIndex++;
+                        continue;
+                    }
+                    deleteRect = pointX2 >= bottomX1;
+                    appendRect = pointX1 <= bottomX2;
+                }
+
+                if (deleteRect) {
+                    if (bottomIndex < bottomCount - 1) {
+                        System.arraycopy(bottom, bottomIndex + 1, bottom, bottomIndex, bottomCount - bottomIndex - 1);
+                        rectIndex -= 4;
+                    }
+                    bottomCount--;
+                    lastCount--;
+                }
+
+                if (appendRect) {
+                    int i = rect[0];
+                    bottom[bottomCount++] = i;
+                    rect = MultiRectAreaOp.checkBufSize(rect, 4);
+                    rect[i++] = pointX1;
+                    rect[i++] = lineY;
+                    rect[i++] = pointX2;
+                    rect[i++] = lineY;
+                    pointIndex += 2;
+                }
+            }
+            lineY++;
+
+            invalidate();
+        }
+
+    }
+
+    /**
+     * RectCash provides simple creating MultiRectArea
+     */
+    public static class RectCash extends MultiRectArea {
+
+        int[] cash;
+
+        public RectCash() {
+            super();
+            cash = new int[MultiRectAreaOp.RECT_CAPACITY];
+            cash[0] = 1;
+        }
+
+        public void addRectCashed(int x1, int y1, int x2, int y2) {
+            addRect(x1, y1, x2, y2);
+            invalidate();
+/*
+            // Exclude from cash unnecessary rectangles
+            int i = 1;
+            while(i < cash[0]) {
+                if (rect[cash[i] + 3] >= y1 - 1) {
+                    if (i > 1) {
+                        System.arraycopy(cash, i, cash, 1, cash[0] - i);
+                    }
+                    break;
+                }
+                i++;
+            }
+            cash[0] -= i - 1;
+
+            // Find in cash rectangle to concatinate
+            i = 1;
+            while(i < cash[0]) {
+                int index = cash[i];
+                if (rect[index + 3] != y1 - 1) {
+                    break;
+                }
+                if (rect[index] == x1 && rect[index + 2] == x2) {
+                    rect[index + 3] += y2 - y1 + 1;
+
+                    int pos = i + 1;
+                    while(pos < cash[0]) {
+                        if (rect[index + 3] <= rect[cash[i] + 3]) {
+                            System.arraycopy(cash, i + 1, cash, i, pos - i);
+                            break;
+                        }
+                        i++;
+                    }
+                    cash[pos - 1] = index;
+
+                    invalidate();
+                    return;
+                }
+                i++;
+            }
+
+            // Add rectangle to buffer
+            int index = rect[0];
+            rect = MultiRectAreaOp.checkBufSize(rect, 4);
+            rect[index + 0] = x1;
+            rect[index + 1] = y1;
+            rect[index + 2] = x2;
+            rect[index + 3] = y2;
+
+            // Add rectangle to cash
+            int length = cash[0];
+            cash = MultiRectAreaOp.checkBufSize(cash, 1);
+            while(i < length) {
+                if (y2 <= rect[cash[i] + 3]) {
+                    System.arraycopy(cash, i, cash, i + 1, length - i);
+                    break;
+                }
+                i++;
+            }
+            cash[i] = index;
+            invalidate();
+*/
+        }
+
+        public void addRectCashed(int[] rect, int rectOff, int rectLength) {
+            for(int i = rectOff; i < rectOff + rectLength;) {
+                addRect(rect[i++], rect[i++], rect[i++], rect[i++]);
+//              addRectCashed(rect[i++], rect[i++], rect[i++], rect[i++]);
+            }
+        }
+
+    }
+
+    /**
+     * MultiRectArea path iterator
+     */
+    class Iterator implements PathIterator {
+
+        int type;
+        int index;
+        int pos;
+
+        int[] rect;
+        AffineTransform t;
+
+        Iterator(MultiRectArea mra, AffineTransform t) {
+            rect = new int[mra.rect[0] - 1];
+            System.arraycopy(mra.rect, 1, rect, 0, rect.length);
+            this.t = t;
+        }
+
+        public int getWindingRule() {
+            return WIND_NON_ZERO;
+        }
+
+        public boolean isDone() {
+            return pos >= rect.length;
+        }
+
+        public void next() {
+            if (index == 4) {
+                pos += 4;
+            }
+            index = (index + 1) % 5;
+        }
+
+        public int currentSegment(double[] coords) {
+            if (isDone()) {
+                // awt.4B=Iiterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = 0;
+
+            switch(index) {
+            case 0 :
+                type = SEG_MOVETO;
+                coords[0] = rect[pos + 0];
+                coords[1] = rect[pos + 1];
+                break;
+            case 1:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 2];
+                coords[1] = rect[pos + 1];
+                break;
+            case 2:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 2];
+                coords[1] = rect[pos + 3];
+                break;
+            case 3:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 0];
+                coords[1] = rect[pos + 3];
+                break;
+            case 4:
+                type = SEG_CLOSE;
+                break;
+            }
+
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+        public int currentSegment(float[] coords) {
+            if (isDone()) {
+                // awt.4B=Iiterator out of bounds
+                throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
+            }
+            int type = 0;
+
+            switch(index) {
+            case 0 :
+                type = SEG_MOVETO;
+                coords[0] = rect[pos + 0];
+                coords[1] = rect[pos + 1];
+                break;
+            case 1:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 2];
+                coords[1] = rect[pos + 1];
+                break;
+            case 2:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 2];
+                coords[1] = rect[pos + 3];
+                break;
+            case 3:
+                type = SEG_LINETO;
+                coords[0] = rect[pos + 0];
+                coords[1] = rect[pos + 3];
+                break;
+            case 4:
+                type = SEG_CLOSE;
+                break;
+            }
+
+            if (t != null) {
+                t.transform(coords, 0, coords, 0, 1);
+            }
+            return type;
+        }
+
+    }
+
+    /**
+     * Constructs a new empty MultiRectArea 
+     */
+    public MultiRectArea() {
+        rect = MultiRectAreaOp.createBuf(0);
+    }
+
+    public MultiRectArea(boolean sorted) {
+       this();
+       this.sorted = sorted;
+    }
+    
+    /**
+     * Constructs a new MultiRectArea as a copy of another one 
+     */
+    public MultiRectArea(MultiRectArea mra) {
+        if (mra == null) {
+            rect = MultiRectAreaOp.createBuf(0);
+        } else {
+            rect = new int[mra.rect.length];
+            System.arraycopy(mra.rect, 0, rect, 0, mra.rect.length);
+            check(this, "MultiRectArea(MRA)"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Constructs a new MultiRectArea consists of single rectangle 
+     */
+    public MultiRectArea(Rectangle r) {
+        rect = MultiRectAreaOp.createBuf(0);
+        if (r != null && !r.isEmpty()) {
+            rect[0] = 5;
+            rect[1] = r.x;
+            rect[2] = r.y;
+            rect[3] = r.x + r.width - 1;
+            rect[4] = r.y + r.height - 1;
+        }
+        check(this, "MultiRectArea(Rectangle)"); //$NON-NLS-1$
+    }
+
+    /**
+     * Constructs a new MultiRectArea consists of single rectangle
+     */
+    public MultiRectArea(int x0, int y0, int x1, int y1) {
+        rect = MultiRectAreaOp.createBuf(0);
+        if (x1 >= x0 && y1 >= y0) {
+            rect[0] = 5;
+            rect[1] = x0;
+            rect[2] = y0;
+            rect[3] = x1;
+            rect[4] = y1;
+        }
+        check(this, "MultiRectArea(Rectangle)"); //$NON-NLS-1$
+    }
+
+    /**
+     * Constructs a new MultiRectArea and append rectangle from buffer
+     */
+    public MultiRectArea(Rectangle[] buf) {
+        this();
+        for (Rectangle element : buf) {
+            add(element);
+        }
+    }
+
+    /**
+     * Constructs a new MultiRectArea and append rectangle from array
+     */
+    public MultiRectArea(ArrayList<Rectangle> buf) {
+        this();
+        for(int i = 0; i < buf.size(); i++) {
+            add(buf.get(i));
+        }
+    }
+
+    /**
+     * Sort rectangle buffer
+     */
+    void resort() {
+        int[] buf = new int[4];
+        for(int i = 1; i < rect[0]; i += 4) {
+            int k = i;
+            int x1 = rect[k];
+            int y1 = rect[k + 1];
+            for(int j = i + 4; j < rect[0]; j += 4) {
+                int x2 = rect[j];
+                int y2 = rect[j + 1];
+                if (y1 > y2 || (y1 == y2 && x1 > x2)) {
+                    x1 = x2;
+                    y1 = y2;
+                    k = j;
+                }
+            }
+            if (k != i) {
+                System.arraycopy(rect, i, buf, 0, 4);
+                System.arraycopy(rect, k, rect, i, 4);
+                System.arraycopy(buf, 0, rect, k, 4);
+            }
+        }
+        invalidate();
+    }
+
+    /**
+     * Tests equals with another object
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof MultiRectArea) {
+            MultiRectArea mra = (MultiRectArea) obj;
+            for(int i = 0; i < rect[0]; i++) {
+                if (rect[i] != mra.rect[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Checks validation of MultiRectArea object
+     */
+    static MultiRectArea check(MultiRectArea mra, String msg) {
+        if (CHECK && mra != null) {
+            if (MultiRectArea.checkValidation(mra.getRectangles(), mra.sorted) != -1) {
+                // awt.4C=Invalid MultiRectArea in method {0}
+                new RuntimeException(Messages.getString("awt.4C", msg)); //$NON-NLS-1$
+            }
+        }
+        return mra;
+    }
+
+    /**
+     * Checks validation of MultiRectArea object
+     */
+    public static int checkValidation(Rectangle[] r, boolean sorted) {
+
+        // Check width and height
+        for(int i = 0; i < r.length; i++) {
+            if (r[i].width <= 0 || r[i].height <= 0) {
+                return i;
+            }
+        }
+
+        // Check order
+        if (sorted) {
+            for(int i = 1; i < r.length; i++) {
+                if (r[i - 1].y > r[i].y) {
+                    return i;
+                }
+                if (r[i - 1].y == r[i].y) {
+                    if (r[i - 1].x > r[i].x) {
+                        return i;
+                    }
+                }
+            }
+        }
+
+        // Check override
+        for(int i = 0; i < r.length; i++) {
+            for(int j = i + 1; j < r.length; j++) {
+                if (r[i].intersects(r[j])) {
+                    return i;
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Assigns rectangle from another buffer
+     */
+    protected void setRect(int[] buf, boolean copy) {
+        if (copy) {
+            rect = new int[buf.length];
+            System.arraycopy(buf, 0, rect, 0, buf.length);
+        } else {
+            rect = buf;
+        }
+        invalidate();
+    }
+
+    /**
+     * Union with another MultiRectArea object
+     */
+    public void add(MultiRectArea mra) {
+        setRect(union(this, mra).rect, false);
+        invalidate();
+    }
+
+    /**
+     * Intersect with another MultiRectArea object
+     */
+    public void intersect(MultiRectArea mra) {
+        setRect(intersect(this, mra).rect, false);
+        invalidate();
+    }
+
+    /**
+     * Subtract another MultiRectArea object
+     */
+    public void substract(MultiRectArea mra) {
+        setRect(subtract(this, mra).rect, false);
+        invalidate();
+    }
+
+    /**
+     * Union with Rectangle object
+     */
+    public void add(Rectangle rect) {
+        setRect(union(this, new MultiRectArea(rect)).rect, false);
+        invalidate();
+    }
+
+    /**
+     * Intersect with Rectangle object
+     */
+    public void intersect(Rectangle rect) {
+        setRect(intersect(this, new MultiRectArea(rect)).rect, false);
+        invalidate();
+    }
+
+    /**
+     * Subtract rectangle object
+     */
+    public void substract(Rectangle rect) {
+        setRect(subtract(this, new MultiRectArea(rect)).rect, false);
+    }
+
+    /**
+     * Union two MutliRectareArea objects
+     */
+    public static MultiRectArea intersect(MultiRectArea src1, MultiRectArea src2) {
+        MultiRectArea res = check(MultiRectAreaOp.Intersection.getResult(src1, src2), "intersect(MRA,MRA)"); //$NON-NLS-1$
+        return res;
+    }
+
+    /**
+     * Intersect two MultiRectArea objects
+     */
+    public static MultiRectArea union(MultiRectArea src1, MultiRectArea src2) {
+        MultiRectArea res = check(new MultiRectAreaOp.Union().getResult(src1, src2), "union(MRA,MRA)"); //$NON-NLS-1$
+        return res;
+    }
+
+    /**
+     * Subtract two MultiRectArea objects
+     */
+    public static MultiRectArea subtract(MultiRectArea src1, MultiRectArea src2) {
+        MultiRectArea res = check(MultiRectAreaOp.Subtraction.getResult(src1, src2), "subtract(MRA,MRA)"); //$NON-NLS-1$
+        return res;
+    }
+
+    /**
+     * Print MultiRectArea object to output stream
+     */
+    public static void print(MultiRectArea mra, String msg) {
+        if (mra == null) {
+            System.out.println(msg + "=null"); //$NON-NLS-1$
+        } else {
+            Rectangle[] rects = mra.getRectangles();
+            System.out.println(msg + "(" + rects.length + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+            for (Rectangle element : rects) {
+                System.out.println(
+                        element.x + "," + //$NON-NLS-1$
+                        element.y + "," + //$NON-NLS-1$
+                        (element.x + element.width - 1) + "," + //$NON-NLS-1$
+                        (element.y + element.height - 1));
+            }
+        }
+    }
+
+    /**
+     * Translate MultiRectArea object by (x, y)
+     */
+    public void translate(int x, int y) {
+        for(int i = 1; i < rect[0];) {
+            rect[i++] += x;
+            rect[i++] += y;
+            rect[i++] += x;
+            rect[i++] += y;
+        }
+
+        if (bounds != null && !bounds.isEmpty()) {
+            bounds.translate(x, y);
+        }
+
+        if (rectangles != null) {
+            for (Rectangle element : rectangles) {
+                element.translate(x, y);
+            }
+        }
+    }
+
+    /**
+     * Add rectangle to the buffer without any checking
+     */
+    public void addRect(int x1, int y1, int x2, int y2) {
+        int i = rect[0];
+        rect = MultiRectAreaOp.checkBufSize(rect, 4);
+        rect[i++] = x1;
+        rect[i++] = y1;
+        rect[i++] = x2;
+        rect[i++] = y2;
+    }
+
+    /**
+     * Tests is MultiRectArea empty 
+     */
+    public boolean isEmpty() {
+        return rect[0] == 1;
+    }
+
+    void invalidate() {
+        bounds = null;
+        rectangles = null;
+    }
+
+    /**
+     * Returns bounds of MultiRectArea object
+     */
+    public Rectangle getBounds() {
+        if (bounds != null) {
+            return bounds;
+        }
+
+        if (isEmpty()) {
+            return bounds = new Rectangle();
+        }
+
+        int x1 = rect[1];
+        int y1 = rect[2];
+        int x2 = rect[3];
+        int y2 = rect[4];
+        
+        for(int i = 5; i < rect[0]; i += 4) {
+            int rx1 = rect[i + 0];
+            int ry1 = rect[i + 1];
+            int rx2 = rect[i + 2];
+            int ry2 = rect[i + 3];
+            if (rx1 < x1) {
+                x1 = rx1;
+            }
+            if (rx2 > x2) {
+                x2 = rx2;
+            }
+            if (ry1 < y1) {
+                y1 = ry1;
+            }
+            if (ry2 > y2) {
+                y2 = ry2;
+            }
+        }
+        
+        return bounds = new Rectangle(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+    }
+
+    /**
+     * Recturn rectangle count in the buffer
+     */
+    public int getRectCount() {
+        return (rect[0] - 1) / 4;
+    }
+
+    /**
+     * Returns Rectangle array 
+     */
+    public Rectangle[] getRectangles() {
+        if (rectangles != null) {
+            return rectangles;
+        }
+
+        rectangles = new Rectangle[(rect[0] - 1) / 4];
+        int j = 0;
+        for(int i = 1; i < rect[0]; i += 4) {
+            rectangles[j++] = new Rectangle(
+                    rect[i],
+                    rect[i + 1],
+                    rect[i + 2] - rect[i] + 1,
+                    rect[i + 3] - rect[i + 1] + 1);
+        }
+        return rectangles;
+    }
+
+    /**
+     * Returns Bounds2D
+     */
+    public Rectangle2D getBounds2D() {
+        return getBounds();
+    }
+
+    /**
+     * Tests does point lie inside MultiRectArea object
+     */
+    public boolean contains(double x, double y) {
+        for(int i = 1; i < rect[0]; i+= 4) {
+            if (rect[i] <= x && x <= rect[i + 2] && rect[i + 1] <= y && y <= rect[i + 3]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Tests does Point2D lie inside MultiRectArea object
+     */
+    public boolean contains(Point2D p) {
+        return contains(p.getX(), p.getY());
+    }
+
+    /**
+     * Tests does rectangle lie inside MultiRectArea object
+     */
+    public boolean contains(double x, double y, double w, double h) {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Tests does Rectangle2D lie inside MultiRectArea object
+     */
+    public boolean contains(Rectangle2D r) {
+        throw new RuntimeException("Not implemented"); //$NON-NLS-1$
+    }
+
+    /**
+     * Tests does rectangle intersect MultiRectArea object
+     */
+    public boolean intersects(double x, double y, double w, double h) {
+        Rectangle r = new Rectangle();
+        r.setRect(x, y, w, h);
+        return intersects(r);
+    }
+
+    /**
+     * Tests does Rectangle2D intersect MultiRectArea object
+     */
+    public boolean intersects(Rectangle2D r) {
+        if (r == null || r.isEmpty()) {
+            return false;
+        }
+        for(int i = 1; i < rect[0]; i+= 4) {
+            if (r.intersects(rect[i], rect[i+1], rect[i + 2]-rect[i]+1, rect[i + 3]-rect[i + 1]+1)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns path iterator
+     */
+    public PathIterator getPathIterator(AffineTransform t, double flatness) {
+        return new Iterator(this, t);
+    }
+
+    /**
+     * Returns path iterator
+     */
+    public PathIterator getPathIterator(AffineTransform t) {
+        return new Iterator(this, t);
+    }
+
+    /**
+     * Returns MultiRectArea object converted to string 
+     */
+    @Override
+    public String toString() {
+        int cnt = getRectCount();
+        StringBuffer sb = new StringBuffer((cnt << 5) + 128);
+        sb.append(getClass().getName()).append(" ["); //$NON-NLS-1$
+        for(int i = 1; i < rect[0]; i += 4) {
+            sb.append(i > 1 ? ", [" : "[").append(rect[i]).append(", ").append(rect[i + 1]). //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            append(", ").append(rect[i + 2] - rect[i] + 1).append(", "). //$NON-NLS-1$ //$NON-NLS-2$
+            append(rect[i + 3] - rect[i + 1] + 1).append("]"); //$NON-NLS-1$
+        }
+        return sb.append("]").toString(); //$NON-NLS-1$
+    }
+
+}
+
diff --git a/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java b/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java
new file mode 100644
index 0000000..c75e203
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java
@@ -0,0 +1,837 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Rectangle;
+
+public class MultiRectAreaOp {
+
+    /**
+     * Rectangle buffer capacity
+     */
+    public static final int RECT_CAPACITY = 16;
+    
+    /**
+     * If number of rectangle in MultiRectArea object less than MAX_SIMPLE simple algorithm applies 
+     */
+    private static final int MAX_SIMPLE = 8;
+
+    /**
+     * Create buffer
+     */
+    public static int[] createBuf(int capacity) {
+        if (capacity == 0) {
+            capacity = RECT_CAPACITY;
+        }
+        int[] buf = new int[capacity];
+        buf[0] = 1;
+        return buf;
+    }
+
+    /**
+     * Checks buffer size and reallocate if necessary  
+     */
+    public static int[] checkBufSize(int[] buf, int capacity) {
+        if (buf[0] + capacity >= buf.length) {
+            int length = buf[0] + (capacity > RECT_CAPACITY ? capacity : RECT_CAPACITY);
+            int[] tmp = new int[length];
+            System.arraycopy(buf, 0, tmp, 0, buf[0]);
+            buf = tmp;
+        }
+        buf[0] += capacity;
+        return buf;
+    }
+
+    /**
+     * Region class provides basic functionlity for MultiRectArea objects to make logical operations 
+     */
+    static class Region {
+
+        int[] region;
+        int[] active;
+        int[] bottom;
+        int index;
+
+        public Region(int[] region) {
+            this.region = region;
+            active = new int[RECT_CAPACITY];
+            bottom = new int[RECT_CAPACITY];
+            active[0] = 1;
+            bottom[0] = 1;
+            index = 1;
+        }
+
+        void addActive(int index) {
+            int length = active[0];
+            active = checkBufSize(active, 4);
+            int i = 1;
+
+            while(i < length) {
+                if (region[index] < active[i]) {
+                    // Insert
+                    System.arraycopy(active, i, active, i + 4, length - i);
+                    length = i;
+                    break;
+                }
+                i += 4;
+            }
+            System.arraycopy(region, index, active, length, 4);
+
+        }
+
+        void findActive(int top, int bottom) {
+            while(index < region[0]) {
+                if (region[index + 1] > bottom) { // y1 > bottom
+                    return;
+                }
+                if (region[index + 3] >= top) { // y2 >= top
+                    addActive(index);
+                }
+                index += 4;
+            }
+        }
+
+        void deleteActive(int bottom) {
+            int length = active[0];
+            for(int i = 1; i < length;) {
+                if (active[i + 3] == bottom) {
+                    length -= 4;
+                    if (i < length) {
+                        System.arraycopy(active, i + 4, active, i, length - i);
+                    }
+                } else {
+                     i += 4;
+                }
+            }
+            active[0] = length;
+        }
+
+        void deleteActive() {
+            int length = active[0];
+            for(int i = length - 4; i > 0; i -= 4) {
+                if (active[i + 1] > active[i + 3]) {
+                    length -= 4;
+                    if (i < length) {
+                        System.arraycopy(active, i + 4, active, i, length - i);
+                    }
+                }
+            }
+            active[0] = length;
+        }
+
+        void createLevel(int[] level) {
+            int levelCount = 1;
+            int topIndex = 1;
+            int i = 1;
+            while(i < region[0]) {
+
+                int top = region[i + 1];
+                int bottom = region[i + 3] + 1;
+                int j = topIndex;
+
+                addTop: {
+                    while(j < levelCount) {
+                        if (level[j] == top) {
+                            break addTop;
+                        }
+                        if (level[j] > top) {
+                            System.arraycopy(level, j, level, j + 1, levelCount - j);
+                            break;
+                        }
+                        j++;
+                    }
+
+                    level[j] = top;
+                    levelCount++;
+                    topIndex = j;
+                }
+
+                addBottom: {
+                    while(j < levelCount) {
+                        if (level[j] == bottom) {
+                            break addBottom;
+                        }
+                        if (level[j] > bottom) {
+                            System.arraycopy(level, j, level, j + 1, levelCount - j);
+                            break;
+                        }
+                        j++;
+                    };
+
+                    level[j] = bottom;
+                    levelCount++;
+                }
+
+                i += 4;
+            }
+            level[0] = levelCount;
+        }
+
+        static void sortOrdered(int[] src1, int[] src2, int[] dst) {
+            int length1 = src1[0];
+            int length2 = src2[0];
+            int count = 1;
+            int i1 = 1;
+            int i2 = 1;
+            int v1 = src1[1];
+            int v2 = src2[1];
+            while(true) {
+
+                LEFT: {
+                    while(i1 < length1) {
+                        v1 = src1[i1];
+                        if (v1 >= v2) {
+                            break LEFT;
+                        }
+                        dst[count++] = v1;
+                        i1++;
+                    }
+                    while(i2 < length2) {
+                        dst[count++] = src2[i2++];
+                    }
+                    dst[0] = count;
+                    return;
+                }
+
+                RIGHT: {
+                    while(i2 < length2) {
+                        v2 = src2[i2];
+                        if (v2 >= v1) {
+                            break RIGHT;
+                        }
+                        dst[count++] = v2;
+                        i2++;
+                    }
+                    while(i1 < length1) {
+                        dst[count++] = src1[i1++];
+                    }
+                    dst[0] = count;
+                    return;
+                }
+
+                if (v1 == v2) {
+                    dst[count++] = v1;
+                    i1++;
+                    i2++;
+                    if (i1 < length1) {
+                        v1 = src1[i1];
+                    }
+                    if (i2 < length2 - 1) {
+                        v2 = src2[i2];
+                    }
+                }
+            }
+            // UNREACHABLE
+        }
+
+    }
+
+    /**
+     * Intersection class provides intersection of two MultiRectAre aobjects
+     */
+    static class Intersection {
+
+        static void intersectRegions(int[] reg1, int[] reg2, MultiRectArea.RectCash dst, int height1, int height2) {
+
+            Region d1 = new Region(reg1);
+            Region d2 = new Region(reg2);
+
+            int[] level = new int[height1 + height2];
+            int[] level1 = new int[height1];
+            int[] level2 = new int[height2];
+            d1.createLevel(level1);
+            d2.createLevel(level2);
+            Region.sortOrdered(level1, level2, level);
+
+            int top;
+            int bottom = level[1] - 1;
+            for(int i = 2; i < level[0]; i++) {
+
+                top = bottom + 1;
+                bottom = level[i] - 1;
+
+                d1.findActive(top, bottom);
+                d2.findActive(top, bottom);
+
+                int i1 = 1;
+                int i2 = 1;
+
+                while(i1 < d1.active[0] && i2 < d2.active[0]) {
+
+                    int x11 = d1.active[i1];
+                    int x12 = d1.active[i1 + 2];
+                    int x21 = d2.active[i2];
+                    int x22 = d2.active[i2 + 2];
+
+                    if (x11 <= x21) {
+                        if (x12 >= x21) {
+                            if (x12 <= x22) {
+                                dst.addRectCashed(x21, top, x12, bottom);
+                                i1 += 4;
+                            } else {
+                                dst.addRectCashed(x21, top, x22, bottom);
+                                i2 += 4;
+                            }
+                        } else {
+                            i1 += 4;
+                        }
+                    } else {
+                        if (x22 >= x11) {
+                            if (x22 <= x12) {
+                                dst.addRectCashed(x11, top, x22, bottom);
+                                i2 += 4;
+                            } else {
+                                dst.addRectCashed(x11, top, x12, bottom);
+                                i1 += 4;
+                            }
+                        } else {
+                            i2 += 4;
+                        }
+                    }
+                }
+
+                d1.deleteActive(bottom);
+                d2.deleteActive(bottom);
+            }
+        }
+
+        static int[] simpleIntersect(MultiRectArea src1, MultiRectArea src2) {
+            int[] rect1 = src1.rect;
+            int[] rect2 = src2.rect;
+            int[] rect = createBuf(0);
+
+            int k = 1;
+            for(int i = 1; i < rect1[0];) {
+
+                int x11 = rect1[i++];
+                int y11 = rect1[i++];
+                int x12 = rect1[i++];
+                int y12 = rect1[i++];
+
+                for(int j = 1; j < rect2[0];) {
+
+                    int x21 = rect2[j++];
+                    int y21 = rect2[j++];
+                    int x22 = rect2[j++];
+                    int y22 = rect2[j++];
+
+                    if (x11 <= x22 && x12 >= x21 &&
+                        y11 <= y22 && y12 >= y21)
+                    {
+                        rect = checkBufSize(rect, 4);
+                        rect[k++] = x11 > x21 ? x11 : x21;
+                        rect[k++] = y11 > y21 ? y11 : y21;
+                        rect[k++] = x12 > x22 ? x22 : x12;
+                        rect[k++] = y12 > y22 ? y22 : y12;
+                    }
+                }
+            }
+
+            rect[0] = k;
+            return rect;
+        }
+
+        public static MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) {
+
+            if (src1 == null || src2 == null || src1.isEmpty() || src2.isEmpty()) {
+                return new MultiRectArea();
+            }
+
+            MultiRectArea.RectCash dst = new MultiRectArea.RectCash();
+
+            if (!src1.sorted || !src2.sorted || 
+               src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 
+            {
+                dst.setRect(simpleIntersect(src1, src2), false);
+            } else {
+                Rectangle bounds1 = src1.getBounds();
+                Rectangle bounds2 = src2.getBounds();
+                Rectangle bounds3 = bounds1.intersection(bounds2);
+                if (bounds3.width > 0 && bounds3.height > 0) {
+                    intersectRegions(src1.rect, src2.rect, dst, bounds1.height + 2, bounds2.height + 2);
+                }
+            }
+
+            return dst;
+        }
+
+    }
+
+    /**
+     * Union class provides union of two MultiRectAre aobjects
+     */
+    static class Union {
+
+        int rx1, rx2;
+        int top, bottom;
+        MultiRectArea.RectCash dst;
+
+        boolean next(Region d, int index) {
+            int x1 = d.active[index];
+            int x2 = d.active[index + 2];
+            boolean res = false;
+
+            if (x2 < rx1 - 1) {
+                res = true;
+                dst.addRectCashed(x1, top, x2, bottom);
+            } else
+                if (x1 > rx2 + 1) {
+                    res = false;
+                    dst.addRectCashed(rx1, top, rx2, bottom);
+                    rx1 = x1;
+                    rx2 = x2;
+                } else {
+                    res = x2 <= rx2;
+                    rx1 = Math.min(x1, rx1);
+                    rx2 = Math.max(x2, rx2);
+                }
+
+            // Top
+            if (d.active[index + 1] < top) {
+                dst.addRectCashed(x1, d.active[index + 1], x2, top - 1);
+            }
+            // Bottom
+            if (d.active[index + 3] > bottom) {
+                d.active[index + 1] = bottom + 1;
+            }
+            return res;
+        }
+
+        void check(Region d, int index, boolean t) {
+            int x1 = d.active[index];
+            int x2 = d.active[index + 2];
+            // Top
+            if (d.active[index + 1] < top) {
+                dst.addRectCashed(x1, d.active[index + 1], x2, top - 1);
+            }
+            if (t) {
+                dst.addRectCashed(x1, top, x2, bottom);
+            }
+            // Bottom
+            if (d.active[index + 3] > bottom) {
+                d.active[index + 1] = bottom + 1;
+            }
+        }
+
+        void unionRegions(int[] reg1, int[] reg2, int height1, int height2) {
+            Region d1 = new Region(reg1);
+            Region d2 = new Region(reg2);
+
+            int[] level = new int[height1 + height2];
+            int[] level1 = new int[height1];
+            int[] level2 = new int[height2];
+            d1.createLevel(level1);
+            d2.createLevel(level2);
+            Region.sortOrdered(level1, level2, level);
+
+            bottom = level[1] - 1;
+            for(int i = 2; i < level[0]; i++) {
+
+                top = bottom + 1;
+                bottom = level[i] - 1;
+
+                d1.findActive(top, bottom);
+                d2.findActive(top, bottom);
+
+                int i1 = 1;
+                int i2 = 1;
+                boolean res1, res2;
+
+                if (d1.active[0] > 1) {
+                    check(d1, 1, false);
+                    rx1 = d1.active[1];
+                    rx2 = d1.active[3];
+                    i1 += 4;
+                    res1 = false;
+                    res2 = true;
+                } else
+                    if (d2.active[0] > 1) {
+                        check(d2, 1, false);
+                        rx1 = d2.active[1];
+                        rx2 = d2.active[3];
+                        i2 += 4;
+                        res1 = true;
+                        res2 = false;
+                    } else {
+                        continue;
+                    }
+
+            outer:
+                while(true) {
+
+                    while (res1) {
+                        if (i1 >= d1.active[0]) {
+                            dst.addRectCashed(rx1, top, rx2, bottom);
+                            while(i2 < d2.active[0]) {
+                                check(d2, i2, true);
+                                i2 += 4;
+                            }
+                            break outer;
+                        }
+                        res1 = next(d1, i1);
+                        i1 += 4;
+                    }
+
+                    while (res2) {
+                        if (i2 >= d2.active[0]) {
+                            dst.addRectCashed(rx1, top, rx2, bottom);
+                            while(i1 < d1.active[0]) {
+                                check(d1, i1, true);
+                                i1 += 4;
+                            }
+                            break outer;
+                        }
+                        res2 = next(d2, i2);
+                        i2 += 4;
+                    }
+
+                    res1 = true;
+                    res2 = true;
+                } // while
+
+                d1.deleteActive(bottom);
+                d2.deleteActive(bottom);
+
+            }
+        }
+
+        static void simpleUnion(MultiRectArea src1, MultiRectArea src2, MultiRectArea dst) {
+            if (src1.getRectCount() < src2.getRectCount()) {
+                simpleUnion(src2, src1, dst);
+            } else {
+                Subtraction.simpleSubtract(src1, src2, dst);
+                int pos = dst.rect[0];
+                int size = src2.rect[0] - 1;
+                dst.rect = checkBufSize(dst.rect, size);
+                System.arraycopy(src2.rect,1, dst.rect, pos, size);
+                dst.resort();
+            }
+        }
+
+        MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) {
+
+            if (src1 == null || src1.isEmpty()) {
+                return new MultiRectArea(src2);
+            }
+
+            if (src2 == null || src2.isEmpty()) {
+                return new MultiRectArea(src1);
+            }
+
+            dst = new MultiRectArea.RectCash();
+
+            if (!src1.sorted || !src2.sorted ||
+               src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 
+            {
+                simpleUnion(src1, src2, dst);
+            } else {
+                Rectangle bounds1 = src1.getBounds();
+                Rectangle bounds2 = src2.getBounds();
+                Rectangle bounds3 = bounds1.intersection(bounds2);
+
+                if (bounds3.width < 0 || bounds3.height < 0) {
+                    if (bounds1.y + bounds1.height < bounds2.y) {
+                        dst.setRect(addVerRegion(src1.rect, src2.rect), false);
+                    } else
+                        if (bounds2.y + bounds2.height < bounds1.y) {
+                            dst.setRect(addVerRegion(src2.rect, src1.rect), false);
+                        } else
+                            if (bounds1.x < bounds2.x) {
+                                dst.setRect(addHorRegion(src1.rect, src2.rect), false);
+                            } else {
+                                dst.setRect(addHorRegion(src2.rect, src1.rect), false);
+                            }
+                } else {
+                    unionRegions(src1.rect, src2.rect, bounds1.height + 2, bounds2.height + 2);
+                }
+            }
+
+            return dst;
+        }
+
+        int[] addVerRegion(int[] top, int[] bottom) {
+            int length = top[0] + bottom[0] - 1;
+            int[] dst = new int[length];
+            dst[0] = length;
+            System.arraycopy(top, 1, dst, 1, top[0] - 1);
+            System.arraycopy(bottom, 1, dst, top[0], bottom[0] - 1);
+            return dst;
+        }
+
+        int[] addHorRegion(int[] left, int[] right) {
+            int count1 = left[0];
+            int count2 = right[0];
+            int[] dst = new int[count1 + count2 + 1];
+            int count = 1;
+            int index1 = 1;
+            int index2 = 1;
+
+            int top1 = left[2];
+            int top2 = right[2];
+            int pos1, pos2;
+
+            while(true) {
+
+                if (index1 >= count1) {
+                    System.arraycopy(right, index2, dst, count, count2 - index2);
+                    count += count2 - index2;
+                    break;
+                }
+                if (index2 >= count2) {
+                    System.arraycopy(left, index1, dst, count, count1 - index1);
+                    count += count1 - index1;
+                    break;
+                }
+
+                if (top1 < top2) {
+                    pos1 = index1;
+                    do {
+                        index1 += 4;
+                    } while (index1 < count1 && (top1 = left[index1 + 1]) < top2);
+                    System.arraycopy(left, pos1, dst, count, index1 - pos1);
+                    count += index1 - pos1;
+                    continue;
+                }
+
+                if (top1 > top2) {
+                    pos2 = index2;
+                    do {
+                        index2 += 4;
+                    } while (index2 < count2 && (top2 = right[index2 + 1]) < top1);
+                    System.arraycopy(right, pos2, dst, count, index2 - pos2);
+                    count += index2 - pos2;
+                    continue;
+                }
+
+                int top = top1;
+                pos1 = index1;
+                pos2 = index2;
+                do  {
+                    index1 += 4;
+                } while(index1 < count1 && (top1 = left[index1 + 1]) == top);
+                do {
+                    index2 += 4;
+                } while(index2 < count2 && (top2 = right[index2 + 1]) == top);
+
+                System.arraycopy(left, pos1, dst, count, index1 - pos1);
+                count += index1 - pos1;
+                System.arraycopy(right, pos2, dst, count, index2 - pos2);
+                count += index2 - pos2;
+            }
+
+            dst[0] = count;
+            return dst;
+        }
+
+    }
+
+    /**
+     * Subtraction class provides subtraction of two MultiRectAre aobjects
+     */
+    static class Subtraction {
+
+        static void subtractRegions(int[] reg1, int[] reg2, MultiRectArea.RectCash dst, int height1, int height2) {
+            Region d1 = new Region(reg1);
+            Region d2 = new Region(reg2);
+
+            int[] level = new int[height1 + height2];
+            int[] level1 = new int[height1];
+            int[] level2 = new int[height2];
+            d1.createLevel(level1);
+            d2.createLevel(level2);
+            Region.sortOrdered(level1, level2, level);
+
+            int top;
+            int bottom = level[1] - 1;
+            for(int i = 2; i < level[0]; i++) {
+
+                top = bottom + 1;
+                bottom = level[i] - 1;
+
+                d1.findActive(top, bottom);
+                if (d1.active[0] == 1) {
+                    d2.deleteActive(bottom);
+                    continue;
+                }
+
+                d2.findActive(top, bottom);
+
+                int i1 = 1;
+                int i2 = 1;
+
+                int rx1 = 0;
+                int rx2 = 0;
+
+                boolean next = true;
+
+                while(true) {
+
+                    if (next) {
+                        next = false;
+                        if (i1 >= d1.active[0]) {
+                            break;
+                        }
+                        // Bottom
+                        d1.active[i1 + 1] = bottom + 1;
+                        rx1 = d1.active[i1];
+                        rx2 = d1.active[i1 + 2];
+                        i1 += 4;
+                    }
+
+                    if (i2 >= d2.active[0]) {
+                        dst.addRectCashed(rx1, top, rx2, bottom);
+                        for(int j = i1; j < d1.active[0]; j += 4) {
+                            dst.addRectCashed(d1.active[j], top, d1.active[j + 2], bottom);
+                            d1.active[j + 1] = bottom + 1;
+                        }
+                        break;
+                    }
+
+                    int x1 = d2.active[i2];
+                    int x2 = d2.active[i2 + 2];
+
+                    if (rx1 < x1) {
+                        if (rx2 >= x1) {
+                            if (rx2 <= x2) {
+                                //  [-----------]
+                                //       [-------------]
+                                dst.addRectCashed(rx1, top, x1 - 1, bottom);
+                                next = true;
+                            } else {
+                                // [-----------------]
+                                //      [------]
+                                dst.addRectCashed(rx1, top, x1 - 1, bottom);
+                                rx1 = x2 + 1;
+                                i2 += 4;
+                            }
+                        } else {
+                            // [-----]
+                            //         [----]
+                            dst.addRectCashed(rx1, top, rx2, bottom);
+                            next = true;
+                        }
+                    } else {
+                        if (rx1 <= x2) {
+                            if (rx2 <= x2) {
+                                //    [------]
+                                //  [-----------]
+                                next = true;
+                            } else {
+                                //     [------------]
+                                // [---------]
+                                rx1 = x2 + 1;
+                                i2 += 4;
+                            }
+                        } else {
+                            //         [----]
+                            // [-----]
+                            i2 += 4;
+                        }
+                    }
+
+                }
+                d1.deleteActive();
+                d2.deleteActive(bottom);
+            }
+        }
+
+        static void subtractRect(int x11, int y11, int x12, int y12, int[] rect, int index, MultiRectArea dst) {
+
+            for(int i = index; i < rect[0]; i += 4) {
+                int x21 = rect[i + 0];
+                int y21 = rect[i + 1];
+                int x22 = rect[i + 2];
+                int y22 = rect[i + 3];
+
+                if (x11 <= x22 && x12 >= x21 && y11 <= y22 && y12 >= y21) {
+                    int top, bottom;
+                    if (y11 < y21) {
+                        subtractRect(x11, y11, x12, y21 - 1, rect, i + 4, dst);
+                        top = y21;
+                    } else {
+                        top = y11;
+                    }
+                    if (y12 > y22) {
+                        subtractRect(x11, y22 + 1, x12, y12, rect, i + 4, dst);
+                        bottom = y22;
+                    } else {
+                        bottom = y12;
+                    }
+                    if (x11 < x21) {
+                        subtractRect(x11, top, x21 - 1, bottom, rect, i + 4, dst);
+                    }
+                    if (x12 > x22) {
+                        subtractRect(x22 + 1, top, x12, bottom, rect, i + 4, dst);
+                    }
+                    return;
+                }
+            }
+            dst.addRect(x11, y11, x12, y12);
+        }
+
+        static void simpleSubtract(MultiRectArea src1, MultiRectArea src2, MultiRectArea dst) {
+            for(int i = 1; i < src1.rect[0]; i += 4) {
+                subtractRect(
+                        src1.rect[i + 0],
+                        src1.rect[i + 1],
+                        src1.rect[i + 2],
+                        src1.rect[i + 3],
+                        src2.rect,
+                        1,
+                        dst);
+            }
+            dst.resort();
+        }
+
+        public static MultiRectArea getResult(MultiRectArea src1, MultiRectArea src2) {
+
+            if (src1 == null || src1.isEmpty()) {
+                return new MultiRectArea();
+            }
+
+            if (src2 == null || src2.isEmpty()) {
+                return new MultiRectArea(src1);
+            }
+
+            MultiRectArea.RectCash dst = new MultiRectArea.RectCash();
+
+            if (!src1.sorted || !src2.sorted ||
+               src1.getRectCount() <= MAX_SIMPLE || src2.getRectCount() <= MAX_SIMPLE) 
+            {
+                simpleSubtract(src1, src2, dst);
+            } else {
+                Rectangle bounds1 = src1.getBounds();
+                Rectangle bounds2 = src2.getBounds();
+                Rectangle bounds3 = bounds1.intersection(bounds2);
+
+                if (bounds3.width > 0 && bounds3.height > 0) {
+                    subtractRegions(src1.rect, src2.rect, dst, bounds1.height + 2, bounds2.height + 2);
+                } else {
+                    dst.setRect(src1.rect, true);
+                }
+            }
+
+            return dst;
+        }
+
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/Surface.java b/awt/org/apache/harmony/awt/gl/Surface.java
new file mode 100644
index 0000000..8b0ae38
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/Surface.java
@@ -0,0 +1,309 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 10.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DirectColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.util.ArrayList;
+
+import org.apache.harmony.awt.gl.color.LUTColorConverter;
+
+
+/**
+ * This class is super class for others types of Surfaces. 
+ * Surface is storing data and data format description, that are using
+ * in blitting operations    
+ */
+public abstract class Surface implements Transparency{
+
+    // Color Space Types
+    public static final int sRGB_CS = 1;
+    public static final int Linear_RGB_CS = 2;
+    public static final int Linear_Gray_CS = 3;
+    public static final int Custom_CS = 0;
+    
+    // Color Model Types
+    public static final int DCM = 1;  // Direct Color Model
+    public static final int ICM = 2;  // Index Color Model
+    public static final int CCM = 3;  // Component Color Model
+
+    // Sample Model Types
+    public static final int SPPSM = 1;  // Single Pixel Packed Sample Model
+    public static final int MPPSM = 2;  // Multi Pixel Packed Sample Model
+    public static final int CSM   = 3;  // Component Sample Model
+    public static final int PISM  = 4;  // Pixel Interleaved Sample Model
+    public static final int BSM   = 5;  // Banded Sample Model
+
+    // Surface Types
+    private static final int ALPHA_MASK = 0xff000000;
+    private static final int RED_MASK = 0x00ff0000;
+    private static final int GREEN_MASK = 0x0000ff00;
+    private static final int BLUE_MASK = 0x000000ff;
+    private static final int RED_BGR_MASK = 0x000000ff;
+    private static final int GREEN_BGR_MASK = 0x0000ff00;
+    private static final int BLUE_BGR_MASK = 0x00ff0000;
+    private static final int RED_565_MASK = 0xf800;
+    private static final int GREEN_565_MASK = 0x07e0;
+    private static final int BLUE_565_MASK = 0x001f;
+    private static final int RED_555_MASK = 0x7c00;
+    private static final int GREEN_555_MASK = 0x03e0;
+    private static final int BLUE_555_MASK = 0x001f;
+
+    static{
+        //???AWT
+        /*
+        System.loadLibrary("gl"); //$NON-NLS-1$
+        initIDs();
+        */
+    }
+
+
+    protected long surfaceDataPtr;        // Pointer for Native Surface data
+    protected int transparency = OPAQUE;
+    protected int width;
+    protected int height;
+
+    /**
+     * This list contains caches with the data of this surface that are valid at the moment.
+     * Surface should clear this list when its data is updated.
+     * Caches may check if they are still valid using isCacheValid method.
+     * When cache gets data from the surface, it should call addValidCache method of the surface.
+     */
+    private final ArrayList<Object> validCaches = new ArrayList<Object>();
+
+    public abstract ColorModel getColorModel();
+    public abstract WritableRaster getRaster();
+    public abstract int getSurfaceType(); // Syrface type. It is equal 
+                                          // BufferedImge type
+    /**
+     * Lock Native Surface data
+     */
+    public abstract long lock();     
+    
+    /**
+     * Unlock Native Surface data 
+     */
+    public abstract void unlock();
+    
+    /**
+     * Dispose Native Surface data
+     */
+    public abstract void dispose();
+    public abstract Surface getImageSurface();
+
+    public long getSurfaceDataPtr(){
+        return surfaceDataPtr;
+    }
+
+    public final boolean isCaheValid(Object cache) {
+        return validCaches.contains(cache);
+    }
+
+    public final void addValidCache(Object cache) {
+        validCaches.add(cache);
+    }
+
+    protected final void clearValidCaches() {
+        validCaches.clear();
+    }
+
+    /**
+     * Returns could or coldn't the Surface be blit by Native blitter 
+     * @return - true if the Surface could be blit by Native blitter, 
+     *           false in other case
+     */
+    public boolean isNativeDrawable(){
+        return true;
+    }
+
+    public int getTransparency() {
+        return transparency;
+    }
+
+    public int getWidth(){
+        return width;
+    }
+
+    public int getHeight(){
+        return height;
+    }
+    
+    /**
+     * If Surface has Raster, this method returns data array of Raster's DataBuffer
+     * @return - data array
+     */
+    public Object getData(){
+        return null;
+    }
+    
+    public boolean invalidated(){
+        return true;
+    }
+    
+    public void validate(){}
+    
+    public void invalidate(){}
+
+    /**
+     * Computation type of BufferedImage or Surface
+     * @param cm - ColorModel
+     * @param raster - WritableRaste
+     * @return - type of BufferedImage
+     */
+    public static int getType(ColorModel cm, WritableRaster raster){
+        int transferType = cm.getTransferType();
+        boolean hasAlpha = cm.hasAlpha();
+        ColorSpace cs = cm.getColorSpace();
+        int csType = cs.getType();
+        SampleModel sm = raster.getSampleModel();
+
+        if(csType == ColorSpace.TYPE_RGB){
+            if(cm instanceof DirectColorModel){
+                DirectColorModel dcm = (DirectColorModel) cm;
+                switch (transferType) {
+                case DataBuffer.TYPE_INT:
+                    if (dcm.getRedMask() == RED_MASK &&
+                            dcm.getGreenMask() == GREEN_MASK &&
+                            dcm.getBlueMask() == BLUE_MASK) {
+                        if (!hasAlpha) {
+                            return BufferedImage.TYPE_INT_RGB;
+                        }
+                        if (dcm.getAlphaMask() == ALPHA_MASK) {
+                            if (dcm.isAlphaPremultiplied()) {
+                                return BufferedImage.TYPE_INT_ARGB_PRE;
+                            }
+                            return BufferedImage.TYPE_INT_ARGB;
+                        }
+                        return BufferedImage.TYPE_CUSTOM;
+                    } else if (dcm.getRedMask() == RED_BGR_MASK &&
+                            dcm.getGreenMask() == GREEN_BGR_MASK &&
+                            dcm.getBlueMask() == BLUE_BGR_MASK) {
+                        if (!hasAlpha) {
+                            return BufferedImage.TYPE_INT_BGR;
+                        }
+                    } else {
+                        return BufferedImage.TYPE_CUSTOM;
+                    }
+                case DataBuffer.TYPE_USHORT:
+                    if (dcm.getRedMask() == RED_555_MASK &&
+                            dcm.getGreenMask() == GREEN_555_MASK &&
+                            dcm.getBlueMask() == BLUE_555_MASK && !hasAlpha) {
+                        return BufferedImage.TYPE_USHORT_555_RGB;
+                    } else if (dcm.getRedMask() == RED_565_MASK &&
+                            dcm.getGreenMask() == GREEN_565_MASK &&
+                            dcm.getBlueMask() == BLUE_565_MASK) {
+                        return BufferedImage.TYPE_USHORT_565_RGB;
+                    }
+                default:
+                    return BufferedImage.TYPE_CUSTOM;
+                }
+            }else if(cm instanceof IndexColorModel){
+                IndexColorModel icm = (IndexColorModel) cm;
+                int pixelBits = icm.getPixelSize();
+                if(transferType == DataBuffer.TYPE_BYTE){
+                    if(sm instanceof MultiPixelPackedSampleModel && !hasAlpha &&
+                        pixelBits < 5){
+                            return BufferedImage.TYPE_BYTE_BINARY;
+                    }else if(pixelBits == 8){
+                        return BufferedImage.TYPE_BYTE_INDEXED;
+                    }
+                }
+                return BufferedImage.TYPE_CUSTOM;
+            }else if(cm instanceof ComponentColorModel){
+                ComponentColorModel ccm = (ComponentColorModel) cm;
+                if(transferType == DataBuffer.TYPE_BYTE &&
+                        sm instanceof ComponentSampleModel){
+                    ComponentSampleModel csm =
+                        (ComponentSampleModel) sm;
+                    int[] offsets = csm.getBandOffsets();
+                    int[] bits = ccm.getComponentSize();
+                    boolean isCustom = false;
+                    for (int i = 0; i < bits.length; i++) {
+                        if (bits[i] != 8 ||
+                               offsets[i] != offsets.length - 1 - i) {
+                            isCustom = true;
+                            break;
+                        }
+                    }
+                    if (!isCustom) {
+                        if (!ccm.hasAlpha()) {
+                            return BufferedImage.TYPE_3BYTE_BGR;
+                        } else if (ccm.isAlphaPremultiplied()) {
+                            return BufferedImage.TYPE_4BYTE_ABGR_PRE;
+                        } else {
+                            return BufferedImage.TYPE_4BYTE_ABGR;
+                        }
+                    }
+                }
+                return BufferedImage.TYPE_CUSTOM;
+            }
+            return BufferedImage.TYPE_CUSTOM;
+        }else if(cs == LUTColorConverter.LINEAR_GRAY_CS){
+            if(cm instanceof ComponentColorModel &&
+                    cm.getNumComponents() == 1){
+                int bits[] = cm.getComponentSize();
+                if(transferType == DataBuffer.TYPE_BYTE &&
+                        bits[0] == 8){
+                    return BufferedImage.TYPE_BYTE_GRAY;
+                }else if(transferType == DataBuffer.TYPE_USHORT &&
+                        bits[0] == 16){
+                    return BufferedImage.TYPE_USHORT_GRAY;
+                }else{
+                    return BufferedImage.TYPE_CUSTOM;
+                }
+            }
+            return BufferedImage.TYPE_CUSTOM;
+        }
+        return BufferedImage.TYPE_CUSTOM;
+    }
+
+    public static Surface getImageSurface(Image image){
+        return AwtImageBackdoorAccessor.getInstance().getImageSurface(image);
+    }
+
+    @Override
+    protected void finalize() throws Throwable{
+        dispose();
+    }
+
+    public static boolean isGrayPallete(IndexColorModel icm){
+        return AwtImageBackdoorAccessor.getInstance().isGrayPallete(icm);
+    }
+
+    /**
+     * Initialization of Native data
+     * 
+     */
+    //???AWT: private static native void initIDs();
+}
diff --git a/awt/org/apache/harmony/awt/gl/TextRenderer.java b/awt/org/apache/harmony/awt/gl/TextRenderer.java
new file mode 100644
index 0000000..f57952d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/TextRenderer.java
@@ -0,0 +1,59 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Graphics2D;
+import java.awt.font.GlyphVector;
+
+public abstract class TextRenderer {
+    
+    /**
+     * Draws string on specified Graphics at desired position.
+     * 
+     * @param g specified Graphics2D object
+     * @param str String object to draw
+     * @param x start X position to draw
+     * @param y start Y position to draw
+     */
+    public abstract void drawString(Graphics2D g, String str, float x, float y);
+
+    /**
+     * Draws string on specified Graphics at desired position.
+     * 
+     * @param g specified Graphics2D object
+     * @param str String object to draw
+     * @param x start X position to draw
+     * @param y start Y position to draw
+     */    
+    public void drawString(Graphics2D g, String str, int x, int y){
+        drawString(g, str, (float)x, (float)y);
+    }
+
+    /**
+     * Draws GlyphVector on specified Graphics at desired position.
+     * 
+     * @param g specified Graphics2D object
+     * @param glyphVector GlyphVector object to draw
+     * @param x start X position to draw
+     * @param y start Y position to draw
+     */
+    public abstract void drawGlyphVector(Graphics2D g, GlyphVector glyphVector, float x, float y);
+}
diff --git a/awt/org/apache/harmony/awt/gl/XORComposite.java b/awt/org/apache/harmony/awt/gl/XORComposite.java
new file mode 100644
index 0000000..e27e1d3
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/XORComposite.java
@@ -0,0 +1,48 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 21.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl;
+
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.RenderingHints;
+import java.awt.image.ColorModel;
+
+public class XORComposite implements Composite {
+
+    Color xorcolor;
+
+    public XORComposite(Color xorcolor){
+        this.xorcolor = xorcolor;
+    }
+
+    public CompositeContext createContext(ColorModel srcCM, ColorModel dstCM,
+            RenderingHints hints) {
+
+        return new ICompositeContext(this, srcCM, dstCM);
+    }
+
+    public Color getXORColor(){
+        return xorcolor;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/color/ColorConverter.java b/awt/org/apache/harmony/awt/gl/color/ColorConverter.java
new file mode 100644
index 0000000..c98e114
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/ColorConverter.java
@@ -0,0 +1,257 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+/**
+ * This class combines ColorScaler, ICC_Transform and NativeImageFormat functionality
+ * in the workflows for different types of input/output pixel data.
+ */
+public class ColorConverter {
+    private ColorScaler scaler = new ColorScaler();
+
+    public void loadScalingData(ColorSpace cs) {
+        scaler.loadScalingData(cs);
+    }
+
+    /**
+     * Translates pixels, stored in source buffered image and writes the data
+     * to the destination image.
+     * @param t - ICC transform
+     * @param src - source image
+     * @param dst - destination image
+     */
+    public void translateColor(ICC_Transform t,
+            BufferedImage src, BufferedImage dst) {
+      NativeImageFormat srcIF = NativeImageFormat.createNativeImageFormat(src);
+      NativeImageFormat dstIF = NativeImageFormat.createNativeImageFormat(dst);
+
+      if (srcIF != null && dstIF != null) {
+          t.translateColors(srcIF, dstIF);
+          return;
+      }
+
+        srcIF = createImageFormat(src);
+        dstIF = createImageFormat(dst);
+
+        short srcChanData[] = (short[]) srcIF.getChannelData();
+        short dstChanData[] = (short[]) dstIF.getChannelData();
+
+        ColorModel srcCM = src.getColorModel();
+        int nColorChannels = srcCM.getNumColorComponents();
+        scaler.loadScalingData(srcCM.getColorSpace()); // input scaling data
+        ColorModel dstCM = dst.getColorModel();
+
+        // Prepare array for alpha channel
+        float alpha[] = null;
+        boolean saveAlpha = srcCM.hasAlpha() && dstCM.hasAlpha();
+        if (saveAlpha) {
+            alpha = new float[src.getWidth()*src.getHeight()];
+        }
+
+        WritableRaster wr = src.getRaster();
+        int srcDataPos = 0, alphaPos = 0;
+        float normalizedVal[];
+        for (int row=0, nRows = srcIF.getNumRows(); row<nRows; row++) {
+            for (int col=0, nCols = srcIF.getNumCols(); col<nCols; col++) {
+                normalizedVal = srcCM.getNormalizedComponents(
+                    wr.getDataElements(col, row, null),
+                    null, 0);
+                // Save alpha channel
+                if (saveAlpha) {
+                    // We need nColorChannels'th element cause it's nChannels - 1
+                    alpha[alphaPos++] = normalizedVal[nColorChannels];
+                }
+                scaler.scale(normalizedVal, srcChanData, srcDataPos);
+                srcDataPos += nColorChannels;
+            }
+        }
+
+        t.translateColors(srcIF, dstIF);
+
+        nColorChannels = dstCM.getNumColorComponents();
+        boolean fillAlpha = dstCM.hasAlpha();
+        scaler.loadScalingData(dstCM.getColorSpace()); // output scaling data
+        float dstPixel[] = new float[dstCM.getNumComponents()];
+        int dstDataPos = 0;
+        alphaPos = 0;
+        wr = dst.getRaster();
+
+        for (int row=0, nRows = dstIF.getNumRows(); row<nRows; row++) {
+            for (int col=0, nCols = dstIF.getNumCols(); col<nCols; col++) {
+                scaler.unscale(dstPixel, dstChanData, dstDataPos);
+                dstDataPos += nColorChannels;
+                if (fillAlpha) {
+                    if (saveAlpha) {
+                        dstPixel[nColorChannels] = alpha[alphaPos++];
+                    } else {
+                        dstPixel[nColorChannels] = 1f;
+                    }
+                }
+                wr.setDataElements(col, row,
+                        dstCM.getDataElements(dstPixel, 0 , null));
+            }
+        }
+    }
+
+    /**
+     * Translates pixels, stored in the float data buffer.
+     * Each pixel occupies separate array. Input pixels passed in the buffer
+     * are replaced by output pixels and then the buffer is returned
+     * @param t - ICC transform
+     * @param buffer - data buffer
+     * @param srcCS - source color space
+     * @param dstCS - destination color space
+     * @param nPixels - number of pixels
+     * @return translated pixels
+     */
+    public float[][] translateColor(ICC_Transform t,
+            float buffer[][],
+            ColorSpace srcCS,
+            ColorSpace dstCS,
+            int nPixels) {
+        // Scale source data
+        if (srcCS != null) { // if it is null use old scaling data
+            scaler.loadScalingData(srcCS);
+        }
+        int nSrcChannels = t.getNumInputChannels();
+        short srcShortData[] = new short[nPixels*nSrcChannels];
+        for (int i=0, srcDataPos = 0; i<nPixels; i++) {
+            scaler.scale(buffer[i], srcShortData, srcDataPos);
+            srcDataPos += nSrcChannels;
+        }
+
+        // Apply transform
+        short dstShortData[] = this.translateColor(t, srcShortData, null);
+
+        int nDstChannels = t.getNumOutputChannels();
+        int bufferSize = buffer[0].length;
+        if (bufferSize < nDstChannels + 1) { // Re-allocate buffer if needed
+            for (int i=0; i<nPixels; i++) {
+                // One extra element reserved for alpha
+                buffer[i] = new float[nDstChannels + 1];
+            }
+        }
+
+        // Unscale destination data
+        if (dstCS != null) { // if it is null use old scaling data
+            scaler.loadScalingData(dstCS);
+        }
+        for (int i=0, dstDataPos = 0; i<nPixels; i++) {
+            scaler.unscale(buffer[i], dstShortData, dstDataPos);
+            dstDataPos += nDstChannels;
+        }
+
+        return buffer;
+    }
+
+    /**
+     * Translates pixels stored in a raster.
+     * All data types are supported
+     * @param t - ICC transform
+     * @param src - source pixels
+     * @param dst - destination pixels
+     */
+   public void translateColor(ICC_Transform t, Raster src, WritableRaster dst) {
+        try{
+            NativeImageFormat srcFmt = NativeImageFormat.createNativeImageFormat(src);
+            NativeImageFormat dstFmt = NativeImageFormat.createNativeImageFormat(dst);
+
+          if (srcFmt != null && dstFmt != null) {
+              t.translateColors(srcFmt, dstFmt);
+              return;
+          }
+        } catch (IllegalArgumentException e) {
+      }
+
+        // Go ahead and rescale the source image
+        scaler.loadScalingData(src, t.getSrc());
+        short srcData[] = scaler.scale(src);
+
+        short dstData[] = translateColor(t, srcData, null);
+
+        scaler.loadScalingData(dst, t.getDst());
+        scaler.unscale(dstData, dst);
+   }
+
+    /**
+     * Translates pixels stored in an array of shorts.
+     * Samples are stored one-by-one, i.e. array structure is like following: RGBRGBRGB...
+     * The number of pixels is (size of the array) / (number of components).
+     * @param t - ICC transform
+     * @param src - source pixels
+     * @param dst - destination pixels
+     * @return destination pixels, stored in the array, passed in dst
+     */
+    public short[] translateColor(ICC_Transform t, short src[], short dst[]) {
+        NativeImageFormat srcFmt = createImageFormat(t, src, 0, true);
+        NativeImageFormat dstFmt = createImageFormat(t, dst, srcFmt.getNumCols(), false);
+
+        t.translateColors(srcFmt, dstFmt);
+
+        return (short[]) dstFmt.getChannelData();
+    }
+
+
+    /**
+     * Creates NativeImageFormat from buffered image.
+     * @param bi - buffered image
+     * @return created NativeImageFormat
+     */
+    private NativeImageFormat createImageFormat(BufferedImage bi) {
+        int nRows = bi.getHeight();
+        int nCols = bi.getWidth();
+        int nComps = bi.getColorModel().getNumColorComponents();
+        short imgData[] = new short[nRows*nCols*nComps];
+        return new NativeImageFormat(
+                imgData, nComps, nRows, nCols);
+    }
+
+    /**
+     * Creates one-row NativeImageFormat, using either nCols if it is positive,
+     * or arr.length to determine the number of pixels
+     *
+     * @param t - transform
+     * @param arr - short array or null if nCols is positive
+     * @param nCols - number of pixels in the array or 0 if array is not null
+     * @param in - is it an input or output array
+     * @return one-row NativeImageFormat
+     */
+    private NativeImageFormat createImageFormat(
+            ICC_Transform t, short arr[], int nCols, boolean in
+    ) {
+        int nComponents = in ? t.getNumInputChannels() : t.getNumOutputChannels();
+
+        if (arr == null || arr.length < nCols*nComponents) {
+            arr = new short[nCols*nComponents];
+        }
+
+        if (nCols == 0)
+            nCols = arr.length / nComponents;
+
+        return new NativeImageFormat(arr, nComponents, 1, nCols);
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/color/ColorScaler.java b/awt/org/apache/harmony/awt/gl/color/ColorScaler.java
new file mode 100644
index 0000000..a1cc169
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/ColorScaler.java
@@ -0,0 +1,355 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+
+/**
+ * This class provides functionality for scaling color data when
+ * ranges of the source and destination color values differs. 
+ */
+public class ColorScaler {
+    private static final float MAX_SHORT = 0xFFFF;
+    private static final float MAX_SIGNED_SHORT = 0x7FFF;
+
+    private static final float MAX_XYZ = 1f + (32767f/32768f);
+
+    // Cached values for scaling color data
+    private float[] channelMinValues = null;
+    private float[] channelMulipliers = null; // for scale
+    private float[] invChannelMulipliers = null; // for unscale
+
+    int nColorChannels = 0;
+
+    // For scaling rasters, false if transfer type is double or float
+    boolean isTTypeIntegral = false;
+
+    /**
+     * Loads scaling data for raster. Note, if profile pf is null,
+     * for non-integral data types multipliers are not initialized.
+     * @param r - raster
+     * @param pf - profile which helps to determine the ranges of the color data
+     */
+    public void loadScalingData(Raster r, ICC_Profile pf) {
+        boolean isSrcTTypeIntegral =
+            r.getTransferType() != DataBuffer.TYPE_FLOAT &&
+            r.getTransferType() != DataBuffer.TYPE_DOUBLE;
+        if (isSrcTTypeIntegral)
+            loadScalingData(r.getSampleModel());
+        else if (pf != null)
+            loadScalingData(pf);
+    }
+
+    /**
+     * Use this method only for integral transfer types.
+     * Extracts min/max values from the sample model
+     * @param sm - sample model
+     */
+    public void loadScalingData(SampleModel sm) {
+        // Supposing integral transfer type
+        isTTypeIntegral = true;
+
+        nColorChannels = sm.getNumBands();
+
+        channelMinValues = new float[nColorChannels];
+        channelMulipliers = new float[nColorChannels];
+        invChannelMulipliers = new float[nColorChannels];
+
+        boolean isSignedShort =
+            (sm.getTransferType() == DataBuffer.TYPE_SHORT);
+
+        float maxVal;
+        for (int i=0; i<nColorChannels; i++) {
+            channelMinValues[i] = 0;
+            if (isSignedShort) {
+                channelMulipliers[i] = MAX_SHORT / MAX_SIGNED_SHORT;
+                invChannelMulipliers[i] = MAX_SIGNED_SHORT / MAX_SHORT;
+            } else {
+                maxVal = ((1 << sm.getSampleSize(i)) - 1);
+                channelMulipliers[i] = MAX_SHORT / maxVal;
+                invChannelMulipliers[i] = maxVal / MAX_SHORT;
+            }
+        }
+    }
+
+    /**
+     * Use this method only for double of float transfer types.
+     * Extracts scaling data from the color space signature
+     * and other tags, stored in the profile
+     * @param pf - ICC profile
+     */
+    public void loadScalingData(ICC_Profile pf) {
+        // Supposing double or float transfer type
+        isTTypeIntegral = false;
+
+        nColorChannels = pf.getNumComponents();
+
+        // Get min/max values directly from the profile
+        // Very much like fillMinMaxValues in ICC_ColorSpace
+        float maxValues[] = new float[nColorChannels];
+        float minValues[] = new float[nColorChannels];
+
+        switch (pf.getColorSpaceType()) {
+            case ColorSpace.TYPE_XYZ:
+                minValues[0] = 0;
+                minValues[1] = 0;
+                minValues[2] = 0;
+                maxValues[0] = MAX_XYZ;
+                maxValues[1] = MAX_XYZ;
+                maxValues[2] = MAX_XYZ;
+                break;
+            case ColorSpace.TYPE_Lab:
+                minValues[0] = 0;
+                minValues[1] = -128;
+                minValues[2] = -128;
+                maxValues[0] = 100;
+                maxValues[1] = 127;
+                maxValues[2] = 127;
+                break;
+            default:
+                for (int i=0; i<nColorChannels; i++) {
+                    minValues[i] = 0;
+                    maxValues[i] = 1;
+                }
+        }
+
+        channelMinValues = minValues;
+        channelMulipliers = new float[nColorChannels];
+        invChannelMulipliers = new float[nColorChannels];
+
+        for (int i = 0; i < nColorChannels; i++) {
+            channelMulipliers[i] =
+                MAX_SHORT / (maxValues[i] - channelMinValues[i]);
+
+            invChannelMulipliers[i] =
+                (maxValues[i] - channelMinValues[i]) / MAX_SHORT;
+        }
+    }
+
+    /**
+     * Extracts scaling data from the color space
+     * @param cs - color space
+     */
+    public void loadScalingData(ColorSpace cs) {
+        nColorChannels = cs.getNumComponents();
+
+        channelMinValues = new float[nColorChannels];
+        channelMulipliers = new float[nColorChannels];
+        invChannelMulipliers = new float[nColorChannels];
+
+        for (int i = 0; i < nColorChannels; i++) {
+            channelMinValues[i] = cs.getMinValue(i);
+
+            channelMulipliers[i] =
+                MAX_SHORT / (cs.getMaxValue(i) - channelMinValues[i]);
+
+            invChannelMulipliers[i] =
+                (cs.getMaxValue(i) - channelMinValues[i]) / MAX_SHORT;
+        }
+    }
+
+    /**
+     * Scales and normalizes the whole raster and returns the result
+     * in the float array
+     * @param r - source raster
+     * @return scaled and normalized raster data
+     */
+    public float[][] scaleNormalize(Raster r) {
+        int width = r.getWidth();
+        int height = r.getHeight();
+        float result[][] = new float[width*height][nColorChannels];
+        float normMultipliers[] = new float[nColorChannels];
+
+        int pos = 0;
+        if (isTTypeIntegral) {
+            // Change max value from MAX_SHORT to 1f
+            for (int i=0; i<nColorChannels; i++) {
+                normMultipliers[i] = channelMulipliers[i] / MAX_SHORT;
+            }
+
+            int sample;
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        sample = r.getSample(row, col, chan);
+                        result[pos][chan] = (sample * normMultipliers[chan]);
+                    }
+                    pos++;
+                }
+            }
+        } else { // Just get the samples...
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        result[pos][chan] = r.getSampleFloat(row, col, chan);
+                    }
+                    pos++;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Unscale the whole float array and put the result
+     * in the raster
+     * @param r - destination raster
+     * @param data - input pixels
+     */
+    public void unscaleNormalized(WritableRaster r, float data[][]) {
+        int width = r.getWidth();
+        int height = r.getHeight();
+        float normMultipliers[] = new float[nColorChannels];
+
+        int pos = 0;
+        if (isTTypeIntegral) {
+            // Change max value from MAX_SHORT to 1f
+            for (int i=0; i<nColorChannels; i++) {
+                normMultipliers[i] = invChannelMulipliers[i] * MAX_SHORT;
+            }
+
+            int sample;
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        sample = (int) (data[pos][chan] * normMultipliers[chan] + 0.5f);
+                        r.setSample(row, col, chan, sample);
+                    }
+                    pos++;
+                }
+            }
+        } else { // Just set the samples...
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        r.setSample(row, col, chan, data[pos][chan]);
+                    }
+                    pos++;
+                }
+            }
+        }
+    }
+
+    /**
+     * Scales the whole raster to short and returns the result
+     * in the array
+     * @param r - source raster
+     * @return scaled and normalized raster data
+     */
+    public short[] scale(Raster r) {
+        int width = r.getWidth();
+        int height = r.getHeight();
+        short result[] = new short[width*height*nColorChannels];
+
+        int pos = 0;
+        if (isTTypeIntegral) {
+            int sample;
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        sample = r.getSample(row, col, chan);
+                        result[pos++] =
+                            (short) (sample * channelMulipliers[chan] + 0.5f);
+                    }
+                }
+            }
+        } else {
+            float sample;
+            for (int row=r.getMinX(); row<width; row++) {
+                for (int col=r.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                        sample = r.getSampleFloat(row, col, chan);
+                        result[pos++] = (short) ((sample - channelMinValues[chan])
+                            * channelMulipliers[chan] + 0.5f);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Unscales the whole data array and puts obtained values to the raster
+     * @param data - input data
+     * @param wr - destination raster
+     */
+    public void unscale(short[] data, WritableRaster wr) {
+        int width = wr.getWidth();
+        int height = wr.getHeight();
+
+        int pos = 0;
+        if (isTTypeIntegral) {
+            int sample;
+            for (int row=wr.getMinX(); row<width; row++) {
+                for (int col=wr.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                         sample = (int) ((data[pos++] & 0xFFFF) *
+                                invChannelMulipliers[chan] + 0.5f);
+                         wr.setSample(row, col, chan, sample);
+                    }
+                }
+            }
+        } else {
+            float sample;
+            for (int row=wr.getMinX(); row<width; row++) {
+                for (int col=wr.getMinY(); col<height; col++) {
+                    for (int chan = 0; chan < nColorChannels; chan++) {
+                         sample = (data[pos++] & 0xFFFF) *
+                            invChannelMulipliers[chan] + channelMinValues[chan];
+                         wr.setSample(row, col, chan, sample);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Scales one pixel and puts obtained values to the chanData
+     * @param pixelData - input pixel
+     * @param chanData - output buffer
+     * @param chanDataOffset - output buffer offset
+     */
+    public void scale(float[] pixelData, short[] chanData, int chanDataOffset) {
+        for (int chan = 0; chan < nColorChannels; chan++) {
+            chanData[chanDataOffset + chan] =
+                    (short) ((pixelData[chan] - channelMinValues[chan]) *
+                        channelMulipliers[chan] + 0.5f);
+        }
+    }
+
+    /**
+     * Unscales one pixel and puts obtained values to the pixelData
+     * @param pixelData - output pixel
+     * @param chanData - input buffer
+     * @param chanDataOffset - input buffer offset
+     */
+    public void unscale(float[] pixelData, short[] chanData, int chanDataOffset) {
+        for (int chan = 0; chan < nColorChannels; chan++) {
+            pixelData[chan] = (chanData[chanDataOffset + chan] & 0xFFFF)
+                * invChannelMulipliers[chan] + channelMinValues[chan];
+        }
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/color/ICC_ProfileHelper.java b/awt/org/apache/harmony/awt/gl/color/ICC_ProfileHelper.java
new file mode 100644
index 0000000..2f7e519
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/ICC_ProfileHelper.java
@@ -0,0 +1,82 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ICC_Profile;
+
+/**
+ * Includes utility methods for reading ICC profile data.
+ * Created to provide public access to ICC_Profile methods
+ * for classes outside of java.awt.color
+ */
+public class ICC_ProfileHelper {
+    /**
+     * Utility method.
+     * Gets integer value from the byte array
+     * @param byteArray - byte array
+     * @param idx - byte offset
+     * @return integer value
+     */
+    public static int getIntFromByteArray(byte[] byteArray, int idx) {
+        return (byteArray[idx] & 0xFF)|
+               ((byteArray[idx+1] & 0xFF) << 8) |
+               ((byteArray[idx+2] & 0xFF) << 16)|
+               ((byteArray[idx+3] & 0xFF) << 24);
+    }
+
+    /**
+     * Utility method.
+     * Gets big endian integer value from the byte array
+     * @param byteArray - byte array
+     * @param idx - byte offset
+     * @return integer value
+     */
+    public static int getBigEndianFromByteArray(byte[] byteArray, int idx) {
+        return ((byteArray[idx] & 0xFF) << 24)   |
+               ((byteArray[idx+1] & 0xFF) << 16) |
+               ((byteArray[idx+2] & 0xFF) << 8)  |
+               ( byteArray[idx+3] & 0xFF);
+    }
+
+    /**
+     * Utility method.
+     * Gets short value from the byte array
+     * @param byteArray - byte array
+     * @param idx - byte offset
+     * @return short value
+     */
+    public static short getShortFromByteArray(byte[] byteArray, int idx) {
+        return (short) ((byteArray[idx] & 0xFF) |
+                       ((byteArray[idx+1] & 0xFF) << 8));
+    }
+
+    /**
+     * Used in ICC_Transform class to check the rendering intent of the profile
+     * @param profile - ICC profile
+     * @return rendering intent
+     */
+    public static int getRenderingIntent(ICC_Profile profile) {
+        return getIntFromByteArray(
+                profile.getData(ICC_Profile.icSigHead), // pf header
+                ICC_Profile.icHdrRenderingIntent
+            );
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/color/ICC_Transform.java b/awt/org/apache/harmony/awt/gl/color/ICC_Transform.java
new file mode 100644
index 0000000..27646c4
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/ICC_Transform.java
@@ -0,0 +1,156 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ICC_Profile;
+
+import org.apache.harmony.awt.gl.color.NativeCMM;
+
+/**
+ * This class encapsulates native ICC transform object, is responsible for its
+ * creation, destruction and passing its handle to the native CMM.
+ */
+public class ICC_Transform {
+    private long transformHandle;
+    private int numInputChannels;
+    private int numOutputChannels;
+    private ICC_Profile src;
+    private ICC_Profile dst;
+
+
+    /**
+     * @return Returns the number of input channels.
+     */
+    public int getNumInputChannels() {
+        return numInputChannels;
+    }
+
+    /**
+     * @return Returns the number of output channels.
+     */
+    public int getNumOutputChannels() {
+        return numOutputChannels;
+    }
+
+    /**
+     * @return Returns the dst.
+     */
+    public ICC_Profile getDst() {
+        return dst;
+    }
+
+    /**
+     * @return Returns the src.
+     */
+    public ICC_Profile getSrc() {
+        return src;
+    }
+
+    /**
+     * Constructs a multiprofile ICC transform
+     * @param profiles - list of ICC profiles
+     * @param renderIntents - only hints for CMM
+     */
+    public ICC_Transform(ICC_Profile[] profiles, int[] renderIntents) {
+        int numProfiles = profiles.length;
+
+        long[] profileHandles = new long[numProfiles];
+        for (int i=0; i<numProfiles; i++) {
+            profileHandles[i] = NativeCMM.getHandle(profiles[i]);
+        }
+
+        transformHandle = NativeCMM.cmmCreateMultiprofileTransform(
+                profileHandles,
+                renderIntents);
+
+        src = profiles[0];
+        dst = profiles[numProfiles-1];
+        numInputChannels = src.getNumComponents();
+        numOutputChannels = dst.getNumComponents();
+    }
+
+    /**
+     * This constructor is able to set intents by default
+     * @param profiles - list of ICC profiles
+     */
+    public ICC_Transform(ICC_Profile[] profiles) {
+        int numProfiles = profiles.length;
+        int[] renderingIntents = new int[numProfiles];
+
+        // Default is perceptual
+        int currRenderingIntent = ICC_Profile.icPerceptual;
+
+        // render as colorimetric for output device
+        if (profiles[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) {
+            currRenderingIntent = ICC_Profile.icRelativeColorimetric;
+        }
+
+        // get the transforms from each profile
+        for (int i = 0; i < numProfiles; i++) {
+            // first or last profile cannot be abstract
+            // if profile is abstract, the only possible way is
+            // use AToB0Tag (perceptual), see ICC spec
+            if (i != 0 &&
+               i != numProfiles - 1 &&
+               profiles[i].getProfileClass() == ICC_Profile.CLASS_ABSTRACT
+            ) {
+                currRenderingIntent = ICC_Profile.icPerceptual;
+            }
+
+            renderingIntents[i] = currRenderingIntent;
+            // use current rendering intent
+            // to select LUT from the next profile (chaining)
+            currRenderingIntent =
+                ICC_ProfileHelper.getRenderingIntent(profiles[i]);
+        }
+
+        // Get the profile handles and go ahead
+        long[] profileHandles = new long[numProfiles];
+        for (int i=0; i<numProfiles; i++) {
+            profileHandles[i] = NativeCMM.getHandle(profiles[i]);
+        }
+
+        transformHandle = NativeCMM.cmmCreateMultiprofileTransform(
+                profileHandles,
+                renderingIntents);
+
+        src = profiles[0];
+        dst = profiles[numProfiles-1];
+        numInputChannels = src.getNumComponents();
+        numOutputChannels = dst.getNumComponents();
+    }
+
+    @Override
+    protected void finalize() {
+        if (transformHandle != 0) {
+            NativeCMM.cmmDeleteTransform(transformHandle);
+        }
+    }
+
+    /**
+     * Invokes native color conversion
+     * @param src - source image format
+     * @param dst - destination image format
+     */
+    public void translateColors(NativeImageFormat src, NativeImageFormat dst) {
+        NativeCMM.cmmTranslateColors(transformHandle, src, dst);
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/color/LUTColorConverter.java b/awt/org/apache/harmony/awt/gl/color/LUTColorConverter.java
new file mode 100644
index 0000000..5ea6d25
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/LUTColorConverter.java
@@ -0,0 +1,148 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+/*
+ * Created on 02.11.2004
+ *
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ColorSpace;
+
+public class LUTColorConverter {
+
+    private static byte from8lRGBtosRGB_LUT[];
+
+    private static byte from16lRGBtosRGB_LUT[];
+
+    private static byte fromsRGBto8lRGB_LUT[];
+
+    private static short fromsRGBto16lRGB_LUT[];
+
+    private static byte fromsRGBto8sRGB_LUTs[][];
+
+    public static ColorSpace LINEAR_RGB_CS;
+
+    public static ColorSpace LINEAR_GRAY_CS;
+
+    public static ColorSpace sRGB_CS;
+
+    public LUTColorConverter() {
+    }
+
+    /*
+     * This class prepared and returned lookup tables for conversion color 
+     * values from Linear RGB Color Space to sRGB and vice versa.
+     * Conversion is producing according to sRGB Color Space definition.
+     * "A Standard Default Color Space for the Internet - sRGB",
+     *  Michael Stokes (Hewlett-Packard), Matthew Anderson (Microsoft), 
+     * Srinivasan Chandrasekar (Microsoft), Ricardo Motta (Hewlett-Packard) 
+     * Version 1.10, November 5, 1996 
+     * This document is available: http://www.w3.org/Graphics/Color/sRGB
+     */
+    public static byte[] getFrom8lRGBtosRGB_LUT() {
+        if (from8lRGBtosRGB_LUT == null) {
+            from8lRGBtosRGB_LUT = new byte[256];
+            float v;
+            for (int i = 0; i < 256; i++) {
+                v = (float)i / 255;
+                v = (v <= 0.04045f) ? v / 12.92f :
+                    (float) Math.pow((v + 0.055) / 1.055, 2.4);
+                from8lRGBtosRGB_LUT[i] = (byte) Math.round(v * 255.0f);
+            }
+        }
+        return from8lRGBtosRGB_LUT;
+    }
+
+    public static byte[] getFrom16lRGBtosRGB_LUT() {
+        if (from16lRGBtosRGB_LUT == null) {
+            from16lRGBtosRGB_LUT = new byte[65536];
+            float v;
+            for (int i = 0; i < 65536; i++) {
+                v = (float) i / 65535;
+                v = (v <= 0.04045f) ? v / 12.92f :
+                    (float) Math.pow((v + 0.055) / 1.055, 2.4);
+                from16lRGBtosRGB_LUT[i] = (byte) Math.round(v * 255.0f);
+            }
+        }
+        return from16lRGBtosRGB_LUT;
+    }
+
+    public static byte[] getFromsRGBto8lRGB_LUT() {
+        if (fromsRGBto8lRGB_LUT == null) {
+            fromsRGBto8lRGB_LUT = new byte[256];
+            float v;
+            for (int i = 0; i < 256; i++) {
+                v = (float) i / 255;
+                v = (v <= 0.0031308f) ? v * 12.92f :
+                    ((float) Math.pow(v, 1.0 / 2.4)) * 1.055f - 0.055f;
+                fromsRGBto8lRGB_LUT[i] = (byte) Math.round(v * 255.0f);
+            }
+        }
+        return fromsRGBto8lRGB_LUT;
+    }
+
+    public static short[] getFromsRGBto16lRGB_LUT() {
+        if (fromsRGBto16lRGB_LUT == null) {
+            fromsRGBto16lRGB_LUT = new short[256];
+            float v;
+            for (int i = 0; i < 256; i++) {
+                v = (float) i / 255;
+                v = (v <= 0.0031308f) ? v * 12.92f :
+                    ((float) Math.pow(v, 1.0 / 2.4)) * 1.055f - 0.055f;
+                fromsRGBto16lRGB_LUT[i] = (short) Math.round(v * 65535.0f);
+            }
+        }
+        return fromsRGBto16lRGB_LUT;
+    }
+
+    public static byte[] getsRGBLUT(int bits) {
+        if (bits < 1) return null;
+        int idx = bits -1;
+        if(fromsRGBto8sRGB_LUTs == null) fromsRGBto8sRGB_LUTs = new byte[16][];
+
+        if(fromsRGBto8sRGB_LUTs[idx] == null){
+            fromsRGBto8sRGB_LUTs[idx] = createLUT(bits);
+        }
+        return fromsRGBto8sRGB_LUTs[idx];
+    }
+
+    private static byte[] createLUT(int bits) {
+        int lutSize = (1 << bits);
+        byte lut[] = new byte[lutSize];
+        for (int i = 0; i < lutSize; i++) {
+            lut[i] = (byte) (255.0f / (lutSize - 1) + 0.5f);
+        }
+        return lut;
+    }
+
+    public static boolean is_LINEAR_RGB_CS(ColorSpace cs) {
+        return (cs == LINEAR_RGB_CS);
+    }
+
+    public static boolean is_LINEAR_GRAY_CS(ColorSpace cs) {
+        return (cs == LINEAR_GRAY_CS);
+    }
+
+    public static boolean is_sRGB_CS(ColorSpace cs) {
+        return (cs == sRGB_CS);
+    }
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/color/NativeCMM.java b/awt/org/apache/harmony/awt/gl/color/NativeCMM.java
new file mode 100644
index 0000000..7f8c7e6
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/NativeCMM.java
@@ -0,0 +1,92 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.color.ICC_Profile;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+
+/**
+ * This class is a wrapper for the native CMM library
+ */
+public class NativeCMM {
+
+    /**
+     * Storage for profile handles, since they are private
+     * in ICC_Profile, but we need access to them.
+     */
+    private static HashMap<ICC_Profile, Long> profileHandles = new HashMap<ICC_Profile, Long>();
+
+    private static boolean isCMMLoaded;
+
+    public static void addHandle(ICC_Profile key, long handle) {
+        profileHandles.put(key, new Long(handle));
+    }
+
+    public static void removeHandle(ICC_Profile key) {
+        profileHandles.remove(key);
+    }
+
+    public static long getHandle(ICC_Profile key) {
+        return profileHandles.get(key).longValue();
+    }
+
+    /* ICC profile management */
+    public static native long cmmOpenProfile(byte[] data);
+    public static native void cmmCloseProfile(long profileID);
+    public static native int cmmGetProfileSize(long profileID);
+    public static native void cmmGetProfile(long profileID, byte[] data);
+    public static native int cmmGetProfileElementSize(long profileID, int signature);
+    public static native void cmmGetProfileElement(long profileID, int signature,
+                                           byte[] data);
+    public static native void cmmSetProfileElement(long profileID, int tagSignature,
+                                           byte[] data);
+
+
+    /* ICC transforms */
+    public static native long cmmCreateMultiprofileTransform(
+            long[] profileHandles,
+            int[] renderingIntents
+        );
+    public static native void cmmDeleteTransform(long transformHandle);
+    public static native void cmmTranslateColors(long transformHandle,
+            NativeImageFormat src,
+            NativeImageFormat dest);
+
+    static void loadCMM() {
+        if (!isCMMLoaded) {
+            AccessController.doPrivileged(
+                  new PrivilegedAction<Void>() {
+                    public Void run() {
+                        System.loadLibrary("lcmm"); //$NON-NLS-1$
+                        return null;
+                    }
+            } );
+            isCMMLoaded = true;
+        }
+    }
+
+    /* load native CMM library */
+    static {
+        loadCMM();
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/color/NativeImageFormat.java b/awt/org/apache/harmony/awt/gl/color/NativeImageFormat.java
new file mode 100644
index 0000000..9594047
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/color/NativeImageFormat.java
@@ -0,0 +1,642 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.color;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.util.ArrayList;
+
+import org.apache.harmony.awt.gl.AwtImageBackdoorAccessor;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * This class converts java color/sample models to the LCMS pixel formats.
+ * It also encapsulates all the information about the image format, which native CMM
+ * needs to have in order to read/write data.
+ *
+ * At present planar formats (multiple bands) are not supported
+ * and they are handled as a common (custom) case.
+ * Samples other than 1 - 7 bytes and multiple of 8 bits are
+ * also handled as custom (and won't be supported in the nearest future).
+ */
+class NativeImageFormat {
+    //////////////////////////////////////////////
+    //  LCMS Pixel types
+    private static final int PT_ANY = 0;    // Don't check colorspace
+    // 1 & 2 are reserved
+    private static final int PT_GRAY     = 3;
+    private static final int PT_RGB      = 4;
+    // Skipping other since we don't use them here
+    ///////////////////////////////////////////////
+
+    // Conversion of predefined BufferedImage formats to LCMS formats
+    private static final int INT_RGB_LCMS_FMT =
+        colorspaceSh(PT_RGB)|
+        extraSh(1)|
+        channelsSh(3)|
+        bytesSh(1)|
+        doswapSh(1)|
+        swapfirstSh(1);
+
+    private static final int INT_ARGB_LCMS_FMT = INT_RGB_LCMS_FMT;
+
+    private static final int INT_BGR_LCMS_FMT =
+        colorspaceSh(PT_RGB)|
+        extraSh(1)|
+        channelsSh(3)|
+        bytesSh(1);
+
+    private static final int THREE_BYTE_BGR_LCMS_FMT =
+        colorspaceSh(PT_RGB)|
+        channelsSh(3)|
+        bytesSh(1)|
+        doswapSh(1);
+
+    private static final int FOUR_BYTE_ABGR_LCMS_FMT =
+        colorspaceSh(PT_RGB)|
+        extraSh(1)|
+        channelsSh(3)|
+        bytesSh(1)|
+        doswapSh(1);
+
+    private static final int BYTE_GRAY_LCMS_FMT =
+        colorspaceSh(PT_GRAY)|
+        channelsSh(1)|
+        bytesSh(1);
+
+    private static final int USHORT_GRAY_LCMS_FMT =
+        colorspaceSh(PT_GRAY)|
+        channelsSh(1)|
+        bytesSh(2);
+
+    // LCMS format packed into 32 bit value. For description
+    // of this format refer to LCMS documentation.
+    private int cmmFormat = 0;
+
+    // Dimensions
+    private int rows = 0;
+    private int cols = 0;
+
+    //  Scanline may contain some padding in the end
+    private int scanlineStride = -1;
+
+    private Object imageData;
+    // It's possible to have offset from the beginning of the array
+    private int dataOffset;
+
+    // Has the image alpha channel? If has - here its band band offset goes
+    private int alphaOffset = -1;
+
+    // initializes proper field IDs
+    private static native void initIDs();
+
+    static {
+        NativeCMM.loadCMM();
+        initIDs();
+    }
+
+    ////////////////////////////////////
+    // LCMS image format encoders
+    ////////////////////////////////////
+    private static int colorspaceSh(int s) {
+        return (s << 16);
+    }
+
+    private static int swapfirstSh(int s) {
+        return (s << 14);
+    }
+
+    private static int flavorSh(int s) {
+        return (s << 13);
+    }
+
+    private static int planarSh(int s) {
+        return (s << 12);
+    }
+
+    private static int endianSh(int s) {
+        return (s << 11);
+    }
+
+    private static int doswapSh(int s) {
+        return (s << 10);
+    }
+
+    private static int extraSh(int s) {
+        return (s << 7);
+    }
+
+    private static int channelsSh(int s) {
+        return (s << 3);
+    }
+
+    private static int bytesSh(int s) {
+        return s;
+    }
+    ////////////////////////////////////
+    // End of LCMS image format encoders
+    ////////////////////////////////////
+
+    // Accessors
+    Object getChannelData() {
+        return imageData;
+    }
+
+    int getNumCols() {
+        return cols;
+    }
+
+    int getNumRows() {
+        return rows;
+    }
+
+    // Constructors
+    public NativeImageFormat() {
+    }
+
+    /**
+     * Simple image layout for common case with
+     * not optimized workflow.
+     *
+     * For hifi colorspaces with 5+ color channels imgData
+     * should be <code>byte</code> array.
+     *
+     * For common colorspaces with up to 4 color channels it
+     * should be <code>short</code> array.
+     *
+     * Alpha channel is handled by caller, not by CMS.
+     *
+     * Color channels are in their natural order (not BGR but RGB).
+     *
+     * @param imgData - array of <code>byte</code> or <code>short</code>
+     * @param nChannels - number of channels
+     * @param nRows - number of scanlines in the image
+     * @param nCols - number of pixels in one row of the image
+     */
+    public NativeImageFormat(Object imgData, int nChannels, int nRows, int nCols) {
+        if (imgData instanceof short[]) {
+            cmmFormat |= bytesSh(2);
+        }
+        else if (imgData instanceof byte[]) {
+            cmmFormat |= bytesSh(1);
+        }
+        else
+            // awt.47=First argument should be byte or short array
+            throw new IllegalArgumentException(Messages.getString("awt.47")); //$NON-NLS-1$
+
+        cmmFormat |= channelsSh(nChannels);
+
+        rows = nRows;
+        cols = nCols;
+
+        imageData = imgData;
+
+        dataOffset = 0;
+    }
+
+    /**
+     * Deduces image format from the buffered image type
+     * or color and sample models.
+     * @param bi - image
+     * @return image format object
+     */
+    public static NativeImageFormat createNativeImageFormat(BufferedImage bi) {
+        NativeImageFormat fmt = new NativeImageFormat();
+
+        switch (bi.getType()) {
+            case BufferedImage.TYPE_INT_RGB: {
+                fmt.cmmFormat = INT_RGB_LCMS_FMT;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_ARGB:
+            case BufferedImage.TYPE_INT_ARGB_PRE: {
+                fmt.cmmFormat = INT_ARGB_LCMS_FMT;
+                fmt.alphaOffset = 3;
+                break;
+            }
+
+            case BufferedImage.TYPE_INT_BGR: {
+                fmt.cmmFormat = INT_BGR_LCMS_FMT;
+                break;
+            }
+
+            case BufferedImage.TYPE_3BYTE_BGR: {
+                fmt.cmmFormat = THREE_BYTE_BGR_LCMS_FMT;
+                break;
+            }
+
+            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+            case BufferedImage.TYPE_4BYTE_ABGR: {
+                fmt.cmmFormat = FOUR_BYTE_ABGR_LCMS_FMT;
+                fmt.alphaOffset = 0;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_GRAY: {
+                fmt.cmmFormat = BYTE_GRAY_LCMS_FMT;
+                break;
+            }
+
+            case BufferedImage.TYPE_USHORT_GRAY: {
+                fmt.cmmFormat = USHORT_GRAY_LCMS_FMT;
+                break;
+            }
+
+            case BufferedImage.TYPE_BYTE_BINARY:
+            case BufferedImage.TYPE_USHORT_565_RGB:
+            case BufferedImage.TYPE_USHORT_555_RGB:
+            case BufferedImage.TYPE_BYTE_INDEXED: {
+                // A bunch of unsupported formats
+                return null;
+            }
+
+            default:
+                break; // Try to look at sample model and color model
+        }
+
+
+        if (fmt.cmmFormat == 0) {
+            ColorModel cm = bi.getColorModel();
+            SampleModel sm = bi.getSampleModel();
+
+            if (sm instanceof ComponentSampleModel) {
+                ComponentSampleModel csm = (ComponentSampleModel) sm;
+                fmt.cmmFormat = getFormatFromComponentModel(csm, cm.hasAlpha());
+                fmt.scanlineStride = calculateScanlineStrideCSM(csm, bi.getRaster());
+            } else if (sm instanceof SinglePixelPackedSampleModel) {
+                SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+                fmt.cmmFormat = getFormatFromSPPSampleModel(sppsm, cm.hasAlpha());
+                fmt.scanlineStride = calculateScanlineStrideSPPSM(sppsm, bi.getRaster());
+            }
+
+            if (cm.hasAlpha())
+                fmt.alphaOffset = calculateAlphaOffset(sm, bi.getRaster());
+        }
+
+        if (fmt.cmmFormat == 0)
+            return null;
+
+        if (!fmt.setImageData(bi.getRaster().getDataBuffer())) {
+            return null;
+        }
+
+        fmt.rows = bi.getHeight();
+        fmt.cols = bi.getWidth();
+
+        fmt.dataOffset = bi.getRaster().getDataBuffer().getOffset();
+
+        return fmt;
+    }
+
+    /**
+     * Deduces image format from the raster sample model.
+     * @param r - raster
+     * @return image format object
+     */
+    public static NativeImageFormat createNativeImageFormat(Raster r) {
+        NativeImageFormat fmt = new NativeImageFormat();
+        SampleModel sm = r.getSampleModel();
+
+        // Assume that there's no alpha
+        if (sm instanceof ComponentSampleModel) {
+            ComponentSampleModel csm = (ComponentSampleModel) sm;
+            fmt.cmmFormat = getFormatFromComponentModel(csm, false);
+            fmt.scanlineStride = calculateScanlineStrideCSM(csm, r);
+        } else if (sm instanceof SinglePixelPackedSampleModel) {
+            SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+            fmt.cmmFormat = getFormatFromSPPSampleModel(sppsm, false);
+            fmt.scanlineStride = calculateScanlineStrideSPPSM(sppsm, r);
+        }
+
+        if (fmt.cmmFormat == 0)
+            return null;
+
+        fmt.cols = r.getWidth();
+        fmt.rows = r.getHeight();
+        fmt.dataOffset = r.getDataBuffer().getOffset();
+
+        if (!fmt.setImageData(r.getDataBuffer()))
+            return null;
+
+        return fmt;
+    }
+
+    /**
+     * Obtains LCMS format from the component sample model
+     * @param sm - sample model
+     * @param hasAlpha - true if there's an alpha channel
+     * @return LCMS format
+     */
+    private static int getFormatFromComponentModel(ComponentSampleModel sm, boolean hasAlpha) {
+        // Multiple data arrays (banks) not supported
+        int bankIndex = sm.getBankIndices()[0];
+        for (int i=1; i < sm.getNumBands(); i++) {
+            if (sm.getBankIndices()[i] != bankIndex) {
+                return 0;
+            }
+        }
+
+        int channels = hasAlpha ? sm.getNumBands()-1 : sm.getNumBands();
+        int extra = hasAlpha ? 1 : 0;
+        int bytes = 1;
+        switch (sm.getDataType()) {
+            case DataBuffer.TYPE_BYTE:
+                bytes = 1; break;
+            case DataBuffer.TYPE_SHORT:
+            case DataBuffer.TYPE_USHORT:
+                bytes = 2; break;
+            case DataBuffer.TYPE_INT:
+                bytes = 4; break;
+            case DataBuffer.TYPE_DOUBLE:
+                bytes = 0; break;
+            default:
+                return 0; // Unsupported data type
+        }
+
+        int doSwap = 0;
+        int swapFirst = 0;
+        boolean knownFormat = false;
+
+        int i;
+
+        // "RGBA"
+        for (i=0; i < sm.getNumBands(); i++) {
+            if (sm.getBandOffsets()[i] != i) break;
+        }
+        if (i == sm.getNumBands()) { // Ok, it is it
+            doSwap = 0;
+            swapFirst = 0;
+            knownFormat = true;
+        }
+
+        // "ARGB"
+        if (!knownFormat) {
+            for (i=0; i < sm.getNumBands()-1; i++) {
+                if (sm.getBandOffsets()[i] != i+1) break;
+            }
+            if (sm.getBandOffsets()[i] == 0) i++;
+            if (i == sm.getNumBands()) { // Ok, it is it
+                doSwap = 0;
+                swapFirst = 1;
+                knownFormat = true;
+            }
+        }
+
+        // "BGRA"
+        if (!knownFormat) {
+            for (i=0; i < sm.getNumBands()-1; i++) {
+                if (sm.getBandOffsets()[i] != sm.getNumBands() - 2 - i) break;
+            }
+            if (sm.getBandOffsets()[i] == sm.getNumBands()-1) i++;
+            if (i == sm.getNumBands()) { // Ok, it is it
+                doSwap = 1;
+                swapFirst = 1;
+                knownFormat = true;
+            }
+        }
+
+        // "ABGR"
+        if (!knownFormat) {
+            for (i=0; i < sm.getNumBands(); i++) {
+                if (sm.getBandOffsets()[i] != sm.getNumBands() - 1 - i) break;
+            }
+            if (i == sm.getNumBands()) { // Ok, it is it
+                doSwap = 1;
+                swapFirst = 0;
+                knownFormat = true;
+            }
+        }
+
+        // XXX - Planar formats are not supported yet
+        if (!knownFormat)
+            return 0;
+
+        return
+            channelsSh(channels) |
+            bytesSh(bytes) |
+            extraSh(extra) |
+            doswapSh(doSwap) |
+            swapfirstSh(swapFirst);
+    }
+
+    /**
+     * Obtains LCMS format from the single pixel packed sample model
+     * @param sm - sample model
+     * @param hasAlpha - true if there's an alpha channel
+     * @return LCMS format
+     */
+    private static int getFormatFromSPPSampleModel(SinglePixelPackedSampleModel sm,
+            boolean hasAlpha) {
+        // Can we extract bytes?
+        int mask = sm.getBitMasks()[0] >>> sm.getBitOffsets()[0];
+        if (!(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF))
+            return 0;
+
+        // All masks are same?
+        for (int i = 1; i < sm.getNumBands(); i++) {
+            if ((sm.getBitMasks()[i] >>> sm.getBitOffsets()[i]) != mask)
+                return 0;
+        }
+
+        int pixelSize = 0;
+        // Check if data type is supported
+        if (sm.getDataType() == DataBuffer.TYPE_USHORT)
+            pixelSize = 2;
+        else if (sm.getDataType() == DataBuffer.TYPE_INT)
+            pixelSize = 4;
+        else
+            return 0;
+
+
+        int bytes = 0;
+        switch (mask) {
+            case 0xFF:
+                bytes = 1;
+                break;
+            case 0xFFFF:
+                bytes = 2;
+                break;
+            case 0xFFFFFFFF:
+                bytes = 4;
+                break;
+            default: return 0;
+        }
+
+
+        int channels = hasAlpha ? sm.getNumBands()-1 : sm.getNumBands();
+        int extra = hasAlpha ? 1 : 0;
+        extra +=  pixelSize/bytes - sm.getNumBands(); // Unused bytes?
+
+        // Form an ArrayList containing offset for each band
+        ArrayList<Integer> offsetsLst = new ArrayList<Integer>();
+        for (int k=0; k < sm.getNumBands(); k++) {
+            offsetsLst.add(new Integer(sm.getBitOffsets()[k]/(bytes*8)));
+        }
+
+        // Add offsets for unused space
+        for (int i=0; i<pixelSize/bytes; i++) {
+            if (offsetsLst.indexOf(new Integer(i)) < 0)
+                offsetsLst.add(new Integer(i));
+        }
+
+        int offsets[] = new int[pixelSize/bytes];
+        for (int i=0; i<offsetsLst.size(); i++) {
+            offsets[i] = offsetsLst.get(i).intValue();
+        }
+
+        int doSwap = 0;
+        int swapFirst = 0;
+        boolean knownFormat = false;
+
+        int i;
+
+        // "RGBA"
+        for (i=0; i < pixelSize; i++) {
+            if (offsets[i] != i) break;
+        }
+        if (i == pixelSize) { // Ok, it is it
+            doSwap = 0;
+            swapFirst = 0;
+            knownFormat = true;
+        }
+
+        // "ARGB"
+        if (!knownFormat) {
+            for (i=0; i < pixelSize-1; i++) {
+                if (offsets[i] != i+1) break;
+            }
+            if (offsets[i] == 0) i++;
+            if (i == pixelSize) { // Ok, it is it
+                doSwap = 0;
+                swapFirst = 1;
+                knownFormat = true;
+            }
+        }
+
+        // "BGRA"
+        if (!knownFormat) {
+            for (i=0; i < pixelSize-1; i++) {
+                if (offsets[i] != pixelSize - 2 - i) break;
+            }
+            if (offsets[i] == pixelSize-1) i++;
+            if (i == pixelSize) { // Ok, it is it
+                doSwap = 1;
+                swapFirst = 1;
+                knownFormat = true;
+            }
+        }
+
+        // "ABGR"
+        if (!knownFormat) {
+            for (i=0; i < pixelSize; i++) {
+                if (offsets[i] != pixelSize - 1 - i) break;
+            }
+            if (i == pixelSize) { // Ok, it is it
+                doSwap = 1;
+                swapFirst = 0;
+                knownFormat = true;
+            }
+        }
+
+        // XXX - Planar formats are not supported yet
+        if (!knownFormat)
+            return 0;
+
+        return
+            channelsSh(channels) |
+            bytesSh(bytes) |
+            extraSh(extra) |
+            doswapSh(doSwap) |
+            swapfirstSh(swapFirst);
+    }
+
+    /**
+     * Obtains data array from the DataBuffer object
+     * @param db - data buffer
+     * @return - true if successful
+     */
+    private boolean setImageData(DataBuffer db) {
+        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
+        try {
+            imageData = dbAccess.getData(db);
+        } catch (IllegalArgumentException e) {
+            return false; // Unknown data buffer type
+        }
+
+        return true;
+    }
+
+    /**
+     * Calculates scanline stride in bytes
+     * @param csm - component sample model
+     * @param r - raster
+     * @return scanline stride in bytes
+     */
+    private static int calculateScanlineStrideCSM(ComponentSampleModel csm, Raster r) {
+        if (csm.getScanlineStride() != csm.getPixelStride()*csm.getWidth()) {
+            int dataTypeSize = DataBuffer.getDataTypeSize(r.getDataBuffer().getDataType()) / 8;
+            return csm.getScanlineStride()*dataTypeSize;
+        }
+        return -1;
+    }
+
+    /**
+     * Calculates scanline stride in bytes
+     * @param sppsm - sample model
+     * @param r - raster
+     * @return scanline stride in bytes
+     */
+    private static int calculateScanlineStrideSPPSM(SinglePixelPackedSampleModel sppsm, Raster r) {
+        if (sppsm.getScanlineStride() != sppsm.getWidth()) {
+            int dataTypeSize = DataBuffer.getDataTypeSize(r.getDataBuffer().getDataType()) / 8;
+            return sppsm.getScanlineStride()*dataTypeSize;
+        }
+        return -1;
+    }
+
+    /**
+     * Calculates byte offset of the alpha channel from the beginning of the pixel data
+     * @param sm - sample model
+     * @param r - raster
+     * @return byte offset of the alpha channel
+     */
+    private static int calculateAlphaOffset(SampleModel sm, Raster r) {
+        if (sm instanceof ComponentSampleModel) {
+            ComponentSampleModel csm = (ComponentSampleModel) sm;
+            int dataTypeSize =
+                DataBuffer.getDataTypeSize(r.getDataBuffer().getDataType()) / 8;
+            return
+                csm.getBandOffsets()[csm.getBandOffsets().length - 1] * dataTypeSize;
+        } else if (sm instanceof SinglePixelPackedSampleModel) {
+            SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
+            return sppsm.getBitOffsets()[sppsm.getBitOffsets().length - 1] / 8;
+        } else {
+            return -1; // No offset, don't copy alpha
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidFont.java b/awt/org/apache/harmony/awt/gl/font/AndroidFont.java
new file mode 100644
index 0000000..e8ad1bb
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/AndroidFont.java
@@ -0,0 +1,254 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Font;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.io.File;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import org.apache.harmony.awt.gl.font.FontManager;
+import org.apache.harmony.awt.gl.font.FontPeerImpl;
+import org.apache.harmony.awt.gl.font.Glyph;
+import org.apache.harmony.awt.gl.font.LineMetricsImpl;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * Linux platform font peer implementation based on Xft and FreeType libraries.
+ */
+public class AndroidFont extends FontPeerImpl {
+
+    // Pairs of [begin, end],[..].. unicode ranges values 
+    private int[] fontUnicodeRanges;
+    
+    // table with loaded cached Glyphs
+    private Hashtable glyphs = new Hashtable();
+    
+    // X11 display value
+    private long display = 0;
+
+    // X11 screen value
+    private int screen = 0;
+    
+    public AndroidFont(String fontName, int fontStyle, int fontSize) {
+        /*
+         * Workaround : to initialize awt platform-dependent fields and libraries.
+         */
+        Toolkit.getDefaultToolkit();
+        this.name = fontName;
+        this.size = fontSize;
+        this.style = fontStyle;
+       
+        initAndroidFont();
+    }
+
+    /**
+     * Initializes some native dependent font information, e.g. number of glyphs, 
+     * font metrics, italic angle etc. 
+     */
+    public void initAndroidFont(){
+        this.nlm = new AndroidLineMetrics(this, null, " "); //$NON-NLS-1$
+        this.ascent = nlm.getLogicalAscent();
+        this.descent = nlm.getLogicalDescent();
+        this.height = nlm.getHeight();
+        this.leading = nlm.getLogicalLeading();
+        this.maxAdvance = nlm.getLogicalMaxCharWidth();
+
+        if (this.fontType == FontManager.FONT_TYPE_T1){
+            this.defaultChar = 1;
+        } else {
+            this.defaultChar = 0;
+        }
+
+        this.maxCharBounds = new Rectangle2D.Float(0, -nlm.getAscent(), nlm.getMaxCharWidth(), this.height);
+    }
+
+
+    public boolean canDisplay(char chr) {
+        // TODO: to improve performance there is a sence to implement get
+        // unicode ranges to check if char can be displayed without
+        // native calls in isGlyphExists() method
+
+        return isGlyphExists(chr);
+    }
+
+    public LineMetrics getLineMetrics(String str, FontRenderContext frc, AffineTransform at) {
+
+        // Initialize baseline offsets
+        nlm.getBaselineOffsets();
+        
+        LineMetricsImpl lm = (LineMetricsImpl)(this.nlm.clone());
+        lm.setNumChars(str.length());
+
+        if ((at != null) && (!at.isIdentity())){
+            lm.scale((float)at.getScaleX(), (float)at.getScaleY());
+        }
+
+        return lm;
+    }
+
+    public String getPSName() {
+        return psName;
+    }
+
+    public String getFamily(Locale l) {
+        // TODO: implement localized family
+        if (fontType == FontManager.FONT_TYPE_TT){
+            return this.getFamily();
+        }
+
+        return this.fontFamilyName;
+    }
+
+    public String getFontName(Locale l) {
+        if ((pFont == 0) || (this.fontType == FontManager.FONT_TYPE_T1)){
+            return this.name;
+        }
+
+        return this.getFontName();
+    }
+
+
+    public int getMissingGlyphCode() {
+        return getDefaultGlyph().getGlyphCode();
+    }
+
+    public Glyph getGlyph(char index) {
+        Glyph result = null;
+
+        Object key = new Integer(index);
+        if (glyphs.containsKey(key)) {
+            result = (Glyph) glyphs.get(key);
+        } else {
+            if (this.addGlyph(index)) {
+                result = (Glyph) glyphs.get(key);
+            } else {
+                result = this.getDefaultGlyph();
+            }
+        }
+
+        return result;
+    }
+
+    public Glyph getDefaultGlyph() {
+    	throw new RuntimeException("DefaultGlyphs not implemented!");
+    }
+
+    /**
+     * Disposes native font handle. If this font peer was created from InputStream 
+     * temporary created font resource file is deleted.
+     */
+    public void dispose(){
+        String tempDirName;
+        if (pFont != 0){
+            pFont = 0;
+
+            if (isCreatedFromStream()) {
+                File fontFile = new File(getTempFontFileName());
+                tempDirName = fontFile.getParent();
+                fontFile.delete();
+            }
+        }
+    }
+
+    /**
+     * Add glyph to cached Glyph objects in this LinuxFont object.
+     * 
+     * @param uChar the specified character
+     * @return true if glyph of the specified character exists in this
+     * LinuxFont or this character is escape sequence character.
+     */
+    public boolean addGlyph(char uChar) {
+    	throw new RuntimeException("Not implemented!");    	
+    }
+
+   /**
+    * Adds range of existing glyphs to this LinuxFont object
+    * 
+    * @param uFirst the lowest range's bound, inclusive 
+    * @param uLast the highest range's bound, exclusive
+    */
+    public void addGlyphs(char uFirst, char uLast) {
+    	
+        char index = uFirst;
+        if (uLast < uFirst) {
+            // awt.09=min range bound value is grater than max range bound
+            throw new IllegalArgumentException(Messages.getString("awt.09")); //$NON-NLS-1$
+        }
+        while (index < uLast) {
+            addGlyph(index);
+            index++;
+        }
+        
+    }
+
+    /**
+     * Returns true if specified character has corresopnding glyph, false otherwise.  
+     * 
+     * @param uIndex specified char
+     */
+    public boolean isGlyphExists(char uIndex) {
+    	throw new RuntimeException("DefaultGlyphs not implemented!");
+    }
+
+    /**
+     *  Returns an array of unicode ranges that are supported by this LinuxFont. 
+     */
+    public int[] getUnicodeRanges() {
+        int[] ranges = new int[fontUnicodeRanges.length];
+        System.arraycopy(fontUnicodeRanges, 0, ranges, 0,
+                fontUnicodeRanges.length);
+
+        return ranges;
+    }
+
+    /**
+     * Return Font object if it was successfully embedded in System
+     */
+    public static Font embedFont(String absolutePath){
+    	throw new RuntimeException("embedFont not implemented!");
+    }
+
+    public String getFontName(){
+        if ((pFont != 0) && (faceName == null)){
+            if (this.fontType == FontManager.FONT_TYPE_T1){
+                faceName = getFamily();
+            }
+        }
+        return faceName;
+    }
+
+    public String getFamily() {
+        return fontFamilyName;
+    }
+    
+    /**
+     * Returns initiated FontExtraMetrics instance of this WindowsFont.
+     */
+    public FontExtraMetrics getExtraMetrics(){
+    	throw new RuntimeException("Not implemented!");
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidFontManager.java b/awt/org/apache/harmony/awt/gl/font/AndroidFontManager.java
new file mode 100644
index 0000000..063a256
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/AndroidFontManager.java
@@ -0,0 +1,277 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Font;
+import java.awt.peer.FontPeer;
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.harmony.awt.gl.font.FontManager;
+import org.apache.harmony.awt.gl.font.FontProperty;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+import android.util.Log;
+
+public class AndroidFontManager extends FontManager {
+
+    // set of all available faces supported by a system
+    String faces[];
+
+    // weight names according to xlfd structure
+    public static final String[] LINUX_WEIGHT_NAMES = {
+            "black", "bold", "demibold", "medium", "light" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+    };
+
+    // slant names according to xlfd structure
+    public static final String[] LINUX_SLANT_NAMES = {
+            "i", "o", "r" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    };
+
+    /** Singleton AndroidFontManager instance */
+    public static final AndroidFontManager inst = new AndroidFontManager();
+
+    private AndroidFontManager() {
+        super();
+        faces = new String[] {/*"PLAIN",*/ "NORMAL", "BOLD", "ITALIC", "BOLDITALIC"};
+        initFontProperties();
+    }
+
+    public void initLCIDTable(){
+    	throw new RuntimeException("Not implemented!");
+    }
+
+    /**
+     * Returns temporary File object to store data from InputStream.
+     * This File object saved to `~/.fonts/' folder that is included in the 
+     * list of folders searched for font files, and this is where user-specific 
+     * font files should be installed.
+     */
+    public File getTempFontFile()throws IOException{
+        File fontFile = File.createTempFile("jFont", ".ttf", new File(System.getProperty("user.home") +"/.fonts")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+        fontFile.deleteOnExit();
+
+        return fontFile;
+    }
+
+    /**
+     * Initializes fProperties array field for the current system configuration font
+     * property file.
+     * 
+     * RuntimeException is thrown if font property contains incorrect format of 
+     * xlfd string.
+     * 
+     * @return true is success, false if font property doesn't exist or doesn't
+     * contain roperties. 
+     */
+    public boolean initFontProperties(){
+        File fpFile = getFontPropertyFile();
+        if (fpFile == null){
+            return false;
+        }
+
+        Properties props = getProperties(fpFile);
+        if (props == null){
+            return false;
+        }
+
+        for (int i=0; i < LOGICAL_FONT_NAMES.length; i++){
+            String lName = LOGICAL_FONT_NAMES[i];
+            for (int j=0; j < STYLE_NAMES.length; j++){
+                String styleName = STYLE_NAMES[j];
+                Vector propsVector = new Vector();
+
+                // Number of entries for a logical font
+                int numComp = 0;
+                // Is more entries for this style and logical font name left
+                boolean moreEntries = true;
+                String value = null;
+
+                while(moreEntries){
+                    // Component Font Mappings property name
+                    String property = FONT_MAPPING_KEYS[0].replaceAll("LogicalFontName", lName).replaceAll("StyleName", styleName).replaceAll("ComponentIndex", String.valueOf(numComp)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    value = props.getProperty(property);
+
+                    // If the StyleName is omitted, it's assumed to be plain
+                    if ((j == 0) && (value == null)){
+                        property = FONT_MAPPING_KEYS[1].replaceAll("LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp)); //$NON-NLS-1$ //$NON-NLS-2$
+                        value = props.getProperty(property);
+                    }
+
+                    if (value != null){
+                        String[] fields = parseXLFD(value);
+
+                        if (fields == null){
+                            // awt.08=xfld parse string error: {0}
+                            throw new RuntimeException(Messages.getString("awt.08", value)); //$NON-NLS-1$
+                        }
+                        
+                        String fontName = fields[1];
+                        String weight = fields[2];
+                        String italic = fields[3];
+
+                        int style = getBoldStyle(weight) | getItalicStyle(italic);
+                        // Component Font Character Encodings property value
+                        String encoding = props.getProperty(FONT_CHARACTER_ENCODING.replaceAll("LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp))); //$NON-NLS-1$ //$NON-NLS-2$
+
+                        // Exclusion Ranges property value
+                        String exclString = props.getProperty(EXCLUSION_RANGES.replaceAll("LogicalFontName", lName).replaceAll("ComponentIndex", String.valueOf(numComp))); //$NON-NLS-1$ //$NON-NLS-2$
+                        int[] exclRange = parseIntervals(exclString);
+
+                        FontProperty fp = new AndroidFontProperty(lName, styleName, null, fontName, value, style, exclRange, encoding);
+
+                        propsVector.add(fp);
+                        numComp++;
+                    } else {
+                        moreEntries = false;
+                    }
+                }
+                fProperties.put(LOGICAL_FONT_NAMES[i] + "." + j, propsVector); //$NON-NLS-1$
+            }
+        }
+
+        return true;
+
+    }
+
+    /**
+     * Returns style according to the xlfd weight string.
+     * If weight string is incorrect returned value is Font.PLAIN
+     * 
+     * @param str weight name String
+     */
+    private int getBoldStyle(String str){
+        for (int i = 0; i < LINUX_WEIGHT_NAMES.length;i++){
+            if (str.equalsIgnoreCase(LINUX_WEIGHT_NAMES[i])){
+                return (i < 3) ? Font.BOLD : Font.PLAIN;
+            }
+        }
+        return Font.PLAIN;
+    }
+    
+    /**
+     * Returns style according to the xlfd slant string.
+     * If slant string is incorrect returned value is Font.PLAIN
+     * 
+     * @param str slant name String
+     */
+    private int getItalicStyle(String str){
+        for (int i = 0; i < LINUX_SLANT_NAMES.length;i++){
+            if (str.equalsIgnoreCase(LINUX_SLANT_NAMES[i])){
+                return (i < 2) ? Font.ITALIC : Font.PLAIN;
+            }
+        }
+        return Font.PLAIN;
+    }
+
+    /**
+     * Parse xlfd string and returns array of Strings with separate xlfd 
+     * elements.<p>
+     * 
+     * xlfd format:
+     *      -Foundry-Family-Weight-Slant-Width-Style-PixelSize-PointSize-ResX-ResY-Spacing-AvgWidth-Registry-Encoding
+     * @param xlfd String parameter in xlfd format
+     */
+    public static String[] parseXLFD(String xlfd){
+        int fieldsCount = 14;
+        String fieldsDelim = "-"; //$NON-NLS-1$
+        String[] res = new String[fieldsCount];
+        if (!xlfd.startsWith(fieldsDelim)){
+            return null;
+        }
+
+        xlfd = xlfd.substring(1);
+        int i=0;
+        int pos;
+        for (i=0; i < fieldsCount-1; i++){
+            pos = xlfd.indexOf(fieldsDelim);
+            if (pos != -1){
+                res[i] = xlfd.substring(0, pos);
+                xlfd = xlfd.substring(pos + 1);
+            } else {
+                return null;
+            }
+        }
+        pos = xlfd.indexOf(fieldsDelim);
+
+        // check if no fields left
+        if(pos != -1){
+            return null;
+        }
+        res[fieldsCount-1] = xlfd;
+
+        return res;
+    }
+
+    public int getFaceIndex(String faceName){
+    	
+        for (int i = 0; i < faces.length; i++) {
+            if(faces[i].equals(faceName)){
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public String[] getAllFamilies(){
+        if (allFamilies == null){
+        	allFamilies = new String[]{"sans-serif", "serif", "monospace"};
+        }
+        return allFamilies;
+    }
+
+    public Font[] getAllFonts(){
+        Font[] fonts = new Font[faces.length];
+        for (int i =0; i < fonts.length;i++){
+            fonts[i] = new Font(faces[i], Font.PLAIN, 1);
+        }
+        return fonts;
+    }
+
+    public FontPeer createPhysicalFontPeer(String name, int style, int size) {
+        AndroidFont peer;
+        int familyIndex = getFamilyIndex(name);
+        if (familyIndex != -1){
+            // !! we use family names from the list with cached families because 
+            // they are differ from the family names in xlfd structure, in xlfd 
+            // family names mostly in lower case.
+            peer = new AndroidFont(getFamily(familyIndex), style, size);
+            peer.setFamily(getFamily(familyIndex));
+            return peer;
+        }
+        int faceIndex = getFaceIndex(name); 
+        if (faceIndex != -1){
+
+            peer = new AndroidFont(name, style, size);
+            return peer;
+        }
+        
+        return null;
+    }
+
+    public FontPeer createDefaultFont(int style, int size) {
+    	Log.i("DEFAULT FONT", Integer.toString(style));
+        return new AndroidFont(DEFAULT_NAME, style, size);
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidFontProperty.java b/awt/org/apache/harmony/awt/gl/font/AndroidFontProperty.java
new file mode 100644
index 0000000..0cfdc43
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/AndroidFontProperty.java
@@ -0,0 +1,81 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ *
+ */
+package org.apache.harmony.awt.gl.font;
+
+/**
+ * Android FontProperty implementation, applicable for Linux formats of 
+ * font property files. 
+ */
+public class AndroidFontProperty extends FontProperty {
+    
+    /** xlfd string that is applicable for Linux font.properties */ 
+    String xlfd;
+
+    /** logical name of the font corresponding to this FontProperty */ 
+    String logicalName;
+    
+    /** style name of the font corresponding to this FontProperty */
+    String styleName;
+
+    public AndroidFontProperty(String _logicalName, String _styleName, String _fileName, String _name, String _xlfd, int _style, int[] exclusionRange, String _encoding){
+        this.logicalName = _logicalName;
+        this.styleName = _styleName;
+        this.name = _name;
+        this.encoding = _encoding;
+        this.exclRange = exclusionRange;
+        this.fileName = _fileName;
+        this.xlfd = _xlfd;
+        this.style = _style;
+    }
+    
+    /**
+     * Returns logical name of the font corresponding to this FontProperty. 
+     */
+    public String getLogicalName(){
+        return logicalName;
+    }
+    
+    /**
+     * Returns style name of the font corresponding to this FontProperty. 
+     */
+    public String getStyleName(){
+        return styleName;
+    }
+    
+    /**
+     * Returns xlfd string of this FontProperty. 
+     */
+    public String getXLFD(){
+        return xlfd;
+    }
+
+    public String toString(){
+        return new String(this.getClass().getName() +
+                "[name=" + name + //$NON-NLS-1$
+                ",fileName="+ fileName + //$NON-NLS-1$
+                ",Charset=" + encoding + //$NON-NLS-1$
+                ",exclRange=" + exclRange + //$NON-NLS-1$
+                ",xlfd=" + xlfd + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidGlyphVector.java b/awt/org/apache/harmony/awt/gl/font/AndroidGlyphVector.java
new file mode 100644
index 0000000..4ce5aed
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/AndroidGlyphVector.java
@@ -0,0 +1,219 @@
+package org.apache.harmony.awt.gl.font;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.Font;
+import java.awt.Shape;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import android.util.Log;
+import android.graphics.Path;
+
+public class AndroidGlyphVector extends GlyphVector {
+
+    // array of chars defined in constructor
+    public char[] charVector;
+
+    // array of Glyph objects, that describe information about glyphs
+    public Glyph[] vector;
+
+    // array of default positions of glyphs in GlyphVector
+    // without applying GlyphVector's transform
+    float[] defaultPositions;
+
+    // array of logical positions of glyphs in GlyphVector
+
+    float[] logicalPositions;
+
+    // array of visual (real) positions of glyphs in GlyphVector
+    public float[] visualPositions;
+
+    // FontRenderContext for this vector.
+    protected FontRenderContext vectorFRC;
+
+    // layout flags mask
+    protected int layoutFlags = 0;
+
+    // array of cached glyph outlines 
+    protected Shape[] gvShapes;
+
+    FontPeerImpl peer;
+
+    // font corresponding to the GlyphVector 
+    Font font;
+
+    // ascent of the font
+    float ascent;
+
+    // height of the font
+    float height;
+    
+    // leading of the font
+    float leading;
+    
+    // descent of the font
+    float descent;
+
+    // transform of the GlyphVector
+    AffineTransform transform;
+
+    @SuppressWarnings("deprecation")
+    public AndroidGlyphVector(char[] chars, FontRenderContext frc, Font fnt,
+            int flags) {
+        int len = chars.length;
+        this.font = fnt;
+        LineMetricsImpl lmImpl = (LineMetricsImpl)fnt.getLineMetrics(String.valueOf(chars), frc);     	
+        this.ascent = lmImpl.getAscent();
+        this.height = lmImpl.getHeight();
+        this.leading = lmImpl.getLeading();
+        this.descent = lmImpl.getDescent();
+        this.charVector = chars;
+        this.vectorFRC = frc;
+    }
+
+    public AndroidGlyphVector(char[] chars, FontRenderContext frc, Font fnt) {
+        this(chars, frc, fnt, 0);
+    }
+
+    public AndroidGlyphVector(String str, FontRenderContext frc, Font fnt) {
+        this(str.toCharArray(), frc, fnt, 0);
+    }
+
+    public AndroidGlyphVector(String str, FontRenderContext frc, Font fnt, int flags) {
+        this(str.toCharArray(), frc, fnt, flags);
+    }
+
+	@Override
+	public boolean equals(GlyphVector glyphVector) {
+		return false;
+	}
+
+	public char[] getGlyphs() {
+		return this.charVector;
+	}
+	
+	@Override
+	public Font getFont() {
+		return this.font;
+	}
+
+	@Override
+	public FontRenderContext getFontRenderContext() {
+		return this.vectorFRC;
+	}
+
+	@Override
+	public int getGlyphCode(int glyphIndex) {
+		return charVector[glyphIndex];
+	}
+
+	@Override
+	public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
+			int[] codeReturn) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public Shape getGlyphLogicalBounds(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public GlyphMetrics getGlyphMetrics(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	public Path getAndroidGlyphOutline(int glyphIndex) {
+		AndroidGraphics2D g = AndroidGraphics2D.getInstance();
+        Path path = new Path();
+        char tmp[] = new char[1];
+        tmp[0] = charVector[glyphIndex];
+        ((AndroidGraphics2D)g).getAndroidPaint().getTextPath(new String(tmp), 0, 1, 0, 0, path);
+        return path;
+	}
+	
+	@Override
+	public Shape getGlyphOutline(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public Point2D getGlyphPosition(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
+			float[] positionReturn) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public AffineTransform getGlyphTransform(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public Shape getGlyphVisualBounds(int glyphIndex) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public Rectangle2D getLogicalBounds() {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public int getNumGlyphs() {
+		return charVector.length;
+	}
+
+	@Override
+	public Shape getOutline(float x, float y) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public Shape getOutline() {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	public Path getAndroidOutline() {
+		AndroidGraphics2D g = AndroidGraphics2D.getInstance();
+        Path path = new Path();
+        ((AndroidGraphics2D)g).getAndroidPaint().getTextPath(new String(charVector), 0, charVector.length, 0, 0, path);
+        return path;
+	}
+
+	@Override
+	public Rectangle2D getVisualBounds() {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public void performDefaultLayout() {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public void setGlyphPosition(int glyphIndex, Point2D newPos) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+	@Override
+	public void setGlyphTransform(int glyphIndex, AffineTransform trans) {
+		throw new RuntimeException("Not implemented!");
+	}
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/AndroidLineMetrics.java b/awt/org/apache/harmony/awt/gl/font/AndroidLineMetrics.java
new file mode 100644
index 0000000..f37be6d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/AndroidLineMetrics.java
@@ -0,0 +1,120 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.FontRenderContext;
+import org.apache.harmony.awt.gl.font.LineMetricsImpl;
+
+
+/**
+ *
+ * Linux implementation of LineMetrics class
+ */
+public class AndroidLineMetrics extends LineMetricsImpl {
+    
+    /**
+     * Constructor
+     */
+    public AndroidLineMetrics(    AndroidFont fnt,
+                                FontRenderContext frc,
+                                String str){
+        numChars = str.length();
+        baseLineIndex = 0;
+
+        ascent = fnt.ascent;    // Ascent of the font
+        descent = -fnt.descent;  // Descent of the font
+        leading = fnt.leading;  // External leading
+
+        height = ascent + descent + leading;    // Height of the font ( == (ascent + descent + leading))
+        underlineThickness = 0.0f;
+        underlineOffset = 0.0f;
+        strikethroughThickness = 0.0f;
+        strikethroughOffset = 0.0f;
+        maxCharWidth = 0.0f;
+
+        //    TODO: Find out pixel metrics
+        /*
+         * positive metrics rounded to the smallest int that is bigger than value
+         * negative metrics rounded to the smallest int that is lesser than value
+         * thicknesses rounded to int ((int)round(value + 0.5))
+         *
+         */
+
+        lAscent = (int)Math.ceil(fnt.ascent);//   // Ascent of the font
+        lDescent = -(int)Math.ceil(fnt.descent);// Descent of the font
+        lLeading = (int)Math.ceil(leading);  // External leading
+
+        lHeight = lAscent + lDescent + lLeading;    // Height of the font ( == (ascent + descent + leading))
+
+        lUnderlineThickness = Math.round(underlineThickness);//(int)metrics[11];
+
+        if (underlineOffset >= 0){
+            lUnderlineOffset = (int)Math.ceil(underlineOffset);
+        } else {
+            lUnderlineOffset = (int)Math.floor(underlineOffset);
+        }
+
+        lStrikethroughThickness = Math.round(strikethroughThickness); //(int)metrics[13];
+
+        if (strikethroughOffset >= 0){
+            lStrikethroughOffset = (int)Math.ceil(strikethroughOffset);
+        } else {
+            lStrikethroughOffset = (int)Math.floor(strikethroughOffset);
+        }
+
+        lMaxCharWidth = (int)Math.ceil(maxCharWidth); //(int)metrics[15];
+        units_per_EM = 0;
+
+    }
+
+    public float[] getBaselineOffsets() {
+        // TODO: implement baseline offsets for TrueType fonts
+        if (baselineOffsets == null){
+            float[] baselineData = null;
+
+            // Temporary workaround:
+            // Commented out native data initialization, since it can 
+            // cause failures with opening files in multithreaded applications.
+            //
+            // TODO: support work with truetype data in multithreaded
+            // applications.
+
+            // If font TrueType data is taken from BASE table
+//            if ((this.font.getFontHandle() != 0) && (font.getFontType() == FontManager.FONT_TYPE_TT)){
+//                baselineData = LinuxNativeFont.getBaselineOffsetsNative(font.getFontHandle(), font.getSize(), ascent, descent, units_per_EM);
+//            }
+//
+                baseLineIndex = 0;
+                baselineOffsets = new float[]{0, (-ascent+descent)/2, -ascent};
+        }
+
+        return baselineOffsets;
+    }
+
+    public int getBaselineIndex() {
+        if (baselineOffsets == null){
+            // get offsets and set correct index
+            getBaselineOffsets();
+        }
+        return baseLineIndex;
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/BasicMetrics.java b/awt/org/apache/harmony/awt/gl/font/BasicMetrics.java
new file mode 100644
index 0000000..c0fb390
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/BasicMetrics.java
@@ -0,0 +1,134 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.LineMetrics;
+import java.awt.font.GraphicAttribute;
+import java.awt.*;
+
+/**
+ * Date: May 14, 2005
+ * Time: 7:44:13 PM
+ *
+ * This class incapsulates text metrics specific for the text layout or
+ * for the separate text segment. Text segment is a text run with the constant direction
+ * and attributes like font, decorations, etc. BasicMetrics is also used to store
+ * calculated text metrics like advance, ascent or descent. this class is very similar to
+ * LineMetrics, but provides some additional info, constructors and is more transparent.
+ */
+public class BasicMetrics {
+    int baseLineIndex;
+
+    float ascent;   // Ascent of the font
+    float descent;  // Descent of the font
+    float leading;  // External leading
+    float advance;
+
+    float italicAngle;
+    float superScriptOffset;
+
+    float underlineOffset;
+    float underlineThickness;
+
+    float strikethroughOffset;
+    float strikethroughThickness;
+
+    /**
+     * Constructs BasicMetrics from LineMetrics and font
+     * @param lm
+     * @param font
+     */
+    BasicMetrics(LineMetrics lm, Font font) {
+        ascent = lm.getAscent();
+        descent = lm.getDescent();
+        leading = lm.getLeading();
+
+        underlineOffset = lm.getUnderlineOffset();
+        underlineThickness = lm.getUnderlineThickness();
+
+        strikethroughOffset = lm.getStrikethroughOffset();
+        strikethroughThickness = lm.getStrikethroughThickness();
+
+        baseLineIndex = lm.getBaselineIndex();
+
+        italicAngle = font.getItalicAngle();
+        superScriptOffset = (float) font.getTransform().getTranslateY();
+    }
+
+    /**
+     * Constructs BasicMetrics from GraphicAttribute.
+     * It gets ascent and descent from the graphic attribute and
+     * computes reasonable defaults for other metrics.
+     * @param ga - graphic attribute
+     */
+    BasicMetrics(GraphicAttribute ga) {
+        ascent = ga.getAscent();
+        descent = ga.getDescent();
+        leading = 2;
+
+        baseLineIndex = ga.getAlignment();
+
+        italicAngle = 0;
+        superScriptOffset = 0;
+
+        underlineOffset = Math.max(descent/2, 1);
+
+        // Just suggested, should be cap_stem_width or something like that
+        underlineThickness = Math.max(ascent/13, 1);
+
+        strikethroughOffset = -ascent/2; // Something like middle of the line
+        strikethroughThickness = underlineThickness;
+    }
+
+    /**
+     * Copies metrics from the TextMetricsCalculator object.
+     * @param tmc - TextMetricsCalculator object
+     */
+    BasicMetrics(TextMetricsCalculator tmc) {
+        ascent = tmc.ascent;
+        descent = tmc.descent;
+        leading = tmc.leading;
+        advance = tmc.advance;
+        baseLineIndex = tmc.baselineIndex;
+    }
+
+    public float getAscent() {
+        return ascent;
+    }
+
+    public float getDescent() {
+        return descent;
+    }
+
+    public float getLeading() {
+        return leading;
+    }
+
+    public float getAdvance() {
+        return advance;
+    }
+
+    public int getBaseLineIndex() {
+        return baseLineIndex;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/CaretManager.java b/awt/org/apache/harmony/awt/gl/font/CaretManager.java
new file mode 100644
index 0000000..b18bdd5
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/CaretManager.java
@@ -0,0 +1,530 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Jun 14, 2005
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.TextHitInfo;
+import java.awt.font.TextLayout;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.*;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class provides functionality for creating caret and highlight shapes
+ * (bidirectional text is also supported, but, unfortunately, not tested yet).
+ */
+public class CaretManager {
+    private TextRunBreaker breaker;
+
+    public CaretManager(TextRunBreaker breaker) {
+        this.breaker = breaker;
+    }
+
+    /**
+     * Checks if TextHitInfo is not out of the text range and throws the
+     * IllegalArgumentException if it is.
+     * @param info - text hit info
+     */
+    private void checkHit(TextHitInfo info) {
+        int idx = info.getInsertionIndex();
+
+        if (idx < 0 || idx > breaker.getCharCount()) {
+            // awt.42=TextHitInfo out of range
+            throw new IllegalArgumentException(Messages.getString("awt.42")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Calculates and returns visual position from the text hit info.
+     * @param hitInfo - text hit info
+     * @return visual index
+     */
+    private int getVisualFromHitInfo(TextHitInfo hitInfo) {
+        final int idx = hitInfo.getCharIndex();
+
+        if (idx >= 0 && idx < breaker.getCharCount()) {
+            int visual = breaker.getVisualFromLogical(idx);
+            // We take next character for (LTR char + TRAILING info) and (RTL + LEADING)
+            if (hitInfo.isLeadingEdge() ^ ((breaker.getLevel(idx) & 0x1) == 0x0)) {
+                visual++;
+            }
+            return visual;
+        } else if (idx < 0) {
+            return breaker.isLTR() ? 0: breaker.getCharCount();
+        } else {
+            return breaker.isLTR() ? breaker.getCharCount() : 0;
+        }
+    }
+
+    /**
+     * Calculates text hit info from the visual position
+     * @param visual - visual position
+     * @return text hit info
+     */
+    private TextHitInfo getHitInfoFromVisual(int visual) {
+        final boolean first = visual == 0;
+
+        if (!(first || visual == breaker.getCharCount())) {
+            int logical = breaker.getLogicalFromVisual(visual);
+            return (breaker.getLevel(logical) & 0x1) == 0x0 ?
+                    TextHitInfo.leading(logical) : // LTR
+                    TextHitInfo.trailing(logical); // RTL
+        } else if (first) {
+            return breaker.isLTR() ?
+                    TextHitInfo.trailing(-1) :
+                    TextHitInfo.leading(breaker.getCharCount());
+        } else { // Last
+            return breaker.isLTR() ?
+                    TextHitInfo.leading(breaker.getCharCount()) :
+                    TextHitInfo.trailing(-1);
+        }
+    }
+
+    /**
+     * Creates caret info. Required for the getCaretInfo
+     * methods of the TextLayout
+     * @param hitInfo - specifies caret position
+     * @return caret info, see TextLayout.getCaretInfo documentation
+     */
+    public float[] getCaretInfo(TextHitInfo hitInfo) {
+        checkHit(hitInfo);
+        float res[] = new float[2];
+
+        int visual = getVisualFromHitInfo(hitInfo);
+        float advance, angle;
+        TextRunSegment seg;
+
+        if (visual < breaker.getCharCount()) {
+            int logIdx = breaker.getLogicalFromVisual(visual);
+            int segmentIdx = breaker.logical2segment[logIdx];
+            seg = breaker.runSegments.get(segmentIdx);
+            advance = seg.x + seg.getAdvanceDelta(seg.getStart(), logIdx);
+            angle = seg.metrics.italicAngle;
+
+        } else { // Last character
+            int logIdx = breaker.getLogicalFromVisual(visual-1);
+            int segmentIdx = breaker.logical2segment[logIdx];
+            seg = breaker.runSegments.get(segmentIdx);
+            advance = seg.x + seg.getAdvanceDelta(seg.getStart(), logIdx+1);
+        }
+
+        angle = seg.metrics.italicAngle;
+
+        res[0] = advance;
+        res[1] = angle;
+
+        return res;
+    }
+
+    /**
+     * Returns the next position to the right from the current caret position
+     * @param hitInfo - current position
+     * @return next position to the right
+     */
+    public TextHitInfo getNextRightHit(TextHitInfo hitInfo) {
+        checkHit(hitInfo);
+        int visual = getVisualFromHitInfo(hitInfo);
+
+        if (visual == breaker.getCharCount()) {
+            return null;
+        }
+
+        TextHitInfo newInfo;
+
+        while(visual <= breaker.getCharCount()) {
+            visual++;
+            newInfo = getHitInfoFromVisual(visual);
+
+            if (newInfo.getCharIndex() >= breaker.logical2segment.length) {
+                return newInfo;
+            }
+
+            if (hitInfo.getCharIndex() >= 0) { // Don't check for leftmost info
+                if (
+                        breaker.logical2segment[newInfo.getCharIndex()] !=
+                        breaker.logical2segment[hitInfo.getCharIndex()]
+                ) {
+                    return newInfo; // We crossed segment boundary
+                }
+            }
+
+            TextRunSegment seg = breaker.runSegments.get(breaker.logical2segment[newInfo
+                    .getCharIndex()]);
+            if (!seg.charHasZeroAdvance(newInfo.getCharIndex())) {
+                return newInfo;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the next position to the left from the current caret position
+     * @param hitInfo - current position
+     * @return next position to the left
+     */
+    public TextHitInfo getNextLeftHit(TextHitInfo hitInfo) {
+        checkHit(hitInfo);
+        int visual = getVisualFromHitInfo(hitInfo);
+
+        if (visual == 0) {
+            return null;
+        }
+
+        TextHitInfo newInfo;
+
+        while(visual >= 0) {
+            visual--;
+            newInfo = getHitInfoFromVisual(visual);
+
+            if (newInfo.getCharIndex() < 0) {
+                return newInfo;
+            }
+
+            // Don't check for rightmost info
+            if (hitInfo.getCharIndex() < breaker.logical2segment.length) {
+                if (
+                        breaker.logical2segment[newInfo.getCharIndex()] !=
+                        breaker.logical2segment[hitInfo.getCharIndex()]
+                ) {
+                    return newInfo; // We crossed segment boundary
+                }
+            }
+
+            TextRunSegment seg = breaker.runSegments.get(breaker.logical2segment[newInfo
+                    .getCharIndex()]);
+            if (!seg.charHasZeroAdvance(newInfo.getCharIndex())) {
+                return newInfo;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * For each visual caret position there are two hits. For the simple LTR text one is
+     * a trailing of the previous char and another is the leading of the next char. This
+     * method returns the opposite hit for the given hit.
+     * @param hitInfo - given hit
+     * @return opposite hit
+     */
+    public TextHitInfo getVisualOtherHit(TextHitInfo hitInfo) {
+        checkHit(hitInfo);
+
+        int idx = hitInfo.getCharIndex();
+
+        int resIdx;
+        boolean resIsLeading;
+
+        if (idx >= 0 && idx < breaker.getCharCount()) { // Hit info in the middle
+            int visual = breaker.getVisualFromLogical(idx);
+
+            // Char is LTR + LEADING info
+            if (((breaker.getLevel(idx) & 0x1) == 0x0) ^ hitInfo.isLeadingEdge()) {
+                visual++;
+                if (visual == breaker.getCharCount()) {
+                    if (breaker.isLTR()) {
+                        resIdx = breaker.getCharCount();
+                        resIsLeading = true;
+                    } else {
+                        resIdx = -1;
+                        resIsLeading = false;
+                    }
+                } else {
+                    resIdx = breaker.getLogicalFromVisual(visual);
+                    if ((breaker.getLevel(resIdx) & 0x1) == 0x0) {
+                        resIsLeading = true;
+                    } else {
+                        resIsLeading = false;
+                    }
+                }
+            } else {
+                visual--;
+                if (visual == -1) {
+                    if (breaker.isLTR()) {
+                        resIdx = -1;
+                        resIsLeading = false;
+                    } else {
+                        resIdx = breaker.getCharCount();
+                        resIsLeading = true;
+                    }
+                } else {
+                    resIdx = breaker.getLogicalFromVisual(visual);
+                    if ((breaker.getLevel(resIdx) & 0x1) == 0x0) {
+                        resIsLeading = false;
+                    } else {
+                        resIsLeading = true;
+                    }
+                }
+            }
+        } else if (idx < 0) { // before "start"
+            if (breaker.isLTR()) {
+                resIdx = breaker.getLogicalFromVisual(0);
+                resIsLeading = (breaker.getLevel(resIdx) & 0x1) == 0x0; // LTR char?
+            } else {
+                resIdx = breaker.getLogicalFromVisual(breaker.getCharCount() - 1);
+                resIsLeading = (breaker.getLevel(resIdx) & 0x1) != 0x0; // RTL char?
+            }
+        } else { // idx == breaker.getCharCount()
+            if (breaker.isLTR()) {
+                resIdx = breaker.getLogicalFromVisual(breaker.getCharCount() - 1);
+                resIsLeading = (breaker.getLevel(resIdx) & 0x1) != 0x0; // LTR char?
+            } else {
+                resIdx = breaker.getLogicalFromVisual(0);
+                resIsLeading = (breaker.getLevel(resIdx) & 0x1) == 0x0; // RTL char?
+            }
+        }
+
+        return resIsLeading ? TextHitInfo.leading(resIdx) : TextHitInfo.trailing(resIdx);
+    }
+
+    public Line2D getCaretShape(TextHitInfo hitInfo, TextLayout layout) {
+        return getCaretShape(hitInfo, layout, true, false, null);
+    }
+
+    /**
+     * Creates a caret shape.
+     * @param hitInfo - hit where to place a caret
+     * @param layout - text layout
+     * @param useItalic - unused for now, was used to create
+     * slanted carets for italic text
+     * @param useBounds - true if the cared should fit into the provided bounds
+     * @param bounds - bounds for the caret
+     * @return caret shape
+     */
+    public Line2D getCaretShape(
+            TextHitInfo hitInfo, TextLayout layout,
+            boolean useItalic, boolean useBounds, Rectangle2D bounds
+    ) {
+        checkHit(hitInfo);
+
+        float x1, x2, y1, y2;
+
+        int charIdx = hitInfo.getCharIndex();
+
+        if (charIdx >= 0 && charIdx < breaker.getCharCount()) {
+            TextRunSegment segment = breaker.runSegments.get(breaker.logical2segment[charIdx]);
+            y1 = segment.metrics.descent;
+            y2 = - segment.metrics.ascent - segment.metrics.leading;
+
+            x1 = x2 = segment.getCharPosition(charIdx) + (hitInfo.isLeadingEdge() ?
+                    0 : segment.getCharAdvance(charIdx));
+            // Decided that straight cursor looks better even for italic fonts,
+            // especially combined with highlighting
+            /*
+            // Not graphics, need to check italic angle and baseline
+            if (layout.getBaseline() >= 0) {
+                if (segment.metrics.italicAngle != 0 && useItalic) {
+                    x1 -= segment.metrics.italicAngle * segment.metrics.descent;
+                    x2 += segment.metrics.italicAngle *
+                        (segment.metrics.ascent + segment.metrics.leading);
+
+                    float baselineOffset =
+                        layout.getBaselineOffsets()[layout.getBaseline()];
+                    y1 += baselineOffset;
+                    y2 += baselineOffset;
+                }
+            }
+            */
+        } else {
+            y1 = layout.getDescent();
+            y2 = - layout.getAscent() - layout.getLeading();
+            x1 = x2 = ((breaker.getBaseLevel() & 0x1) == 0 ^ charIdx < 0) ?
+                    layout.getAdvance() : 0;
+        }
+
+        if (useBounds) {
+            y1 = (float) bounds.getMaxY();
+            y2 = (float) bounds.getMinY();
+
+            if (x2 > bounds.getMaxX()) {
+                x1 = x2 = (float) bounds.getMaxX();
+            }
+            if (x1 < bounds.getMinX()) {
+                x1 = x2 = (float) bounds.getMinX();
+            }
+        }
+
+        return new Line2D.Float(x1, y1, x2, y2);
+    }
+
+    /**
+     * Creates caret shapes for the specified offset. On the boundaries where
+     * the text is changing its direction this method may return two shapes
+     * for the strong and the weak carets, in other cases it would return one.
+     * @param offset - offset in the text.
+     * @param bounds - bounds to fit the carets into
+     * @param policy - caret policy
+     * @param layout - text layout
+     * @return one or two caret shapes
+     */
+    public Shape[] getCaretShapes(
+            int offset, Rectangle2D bounds,
+            TextLayout.CaretPolicy policy, TextLayout layout
+    ) {
+        TextHitInfo hit1 = TextHitInfo.afterOffset(offset);
+        TextHitInfo hit2 = getVisualOtherHit(hit1);
+
+        Shape caret1 = getCaretShape(hit1, layout);
+
+        if (getVisualFromHitInfo(hit1) == getVisualFromHitInfo(hit2)) {
+            return new Shape[] {caret1, null};
+        }
+        Shape caret2 = getCaretShape(hit2, layout);
+
+        TextHitInfo strongHit = policy.getStrongCaret(hit1, hit2, layout);
+        return strongHit.equals(hit1) ?
+                new Shape[] {caret1, caret2} :
+                new Shape[] {caret2, caret1};
+    }
+
+    /**
+     * Connects two carets to produce a highlight shape.
+     * @param caret1 - 1st caret
+     * @param caret2 - 2nd caret
+     * @return highlight shape
+     */
+    GeneralPath connectCarets(Line2D caret1, Line2D caret2) {
+        GeneralPath path = new GeneralPath(GeneralPath.WIND_NON_ZERO);
+        path.moveTo((float) caret1.getX1(), (float) caret1.getY1());
+        path.lineTo((float) caret2.getX1(), (float) caret2.getY1());
+        path.lineTo((float) caret2.getX2(), (float) caret2.getY2());
+        path.lineTo((float) caret1.getX2(), (float) caret1.getY2());
+
+        path.closePath();
+
+        return path;
+    }
+
+    /**
+     * Creates a highlight shape from given two hits. This shape
+     * will always be visually contiguous
+     * @param hit1 - 1st hit
+     * @param hit2 - 2nd hit
+     * @param bounds - bounds to fit the shape into
+     * @param layout - text layout
+     * @return highlight shape
+     */
+    public Shape getVisualHighlightShape(
+            TextHitInfo hit1, TextHitInfo hit2,
+            Rectangle2D bounds, TextLayout layout
+    ) {
+        checkHit(hit1);
+        checkHit(hit2);
+
+        Line2D caret1 = getCaretShape(hit1, layout, false, true, bounds);
+        Line2D caret2 = getCaretShape(hit2, layout, false, true, bounds);
+
+        return connectCarets(caret1, caret2);
+    }
+
+    /**
+     * Suppose that the user visually selected a block of text which has
+     * several different levels (mixed RTL and LTR), so, in the logical
+     * representation of the text this selection may be not contigous.
+     * This methods returns a set of logical ranges for the arbitrary
+     * visual selection represented by two hits.
+     * @param hit1 - 1st hit
+     * @param hit2 - 2nd hit
+     * @return logical ranges for the selection
+     */
+    public int[] getLogicalRangesForVisualSelection(TextHitInfo hit1, TextHitInfo hit2) {
+        checkHit(hit1);
+        checkHit(hit2);
+
+        int visual1 = getVisualFromHitInfo(hit1);
+        int visual2 = getVisualFromHitInfo(hit2);
+
+        if (visual1 > visual2) {
+            int tmp = visual2;
+            visual2 = visual1;
+            visual1 = tmp;
+        }
+
+        // Max level is 255, so we don't need more than 512 entries
+        int results[] = new int[512];
+
+        int prevLogical, logical, runStart, numRuns = 0;
+
+        logical = runStart = prevLogical = breaker.getLogicalFromVisual(visual1);
+
+        // Get all the runs. We use the fact that direction is constant in all runs.
+        for (int i=visual1+1; i<=visual2; i++) {
+            logical = breaker.getLogicalFromVisual(i);
+            int diff = logical-prevLogical;
+
+            // Start of the next run encountered
+            if (diff > 1 || diff < -1) {
+                results[(numRuns)*2] = Math.min(runStart, prevLogical);
+                results[(numRuns)*2 + 1] = Math.max(runStart, prevLogical);
+                numRuns++;
+                runStart = logical;
+            }
+
+            prevLogical = logical;
+        }
+
+        // The last unsaved run
+        results[(numRuns)*2] = Math.min(runStart, logical);
+        results[(numRuns)*2 + 1] = Math.max(runStart, logical);
+        numRuns++;
+
+        int retval[] = new int[numRuns*2];
+        System.arraycopy(results, 0, retval, 0, numRuns*2);
+        return retval;
+    }
+
+    /**
+     * Creates a highlight shape from given two endpoints in the logical
+     * representation. This shape is not always visually contiguous
+     * @param firstEndpoint - 1st logical endpoint
+     * @param secondEndpoint - 2nd logical endpoint
+     * @param bounds - bounds to fit the shape into
+     * @param layout - text layout
+     * @return highlight shape
+     */
+    public Shape getLogicalHighlightShape(
+            int firstEndpoint, int secondEndpoint,
+            Rectangle2D bounds, TextLayout layout
+    ) {
+        GeneralPath res = new GeneralPath();
+
+        for (int i=firstEndpoint; i<=secondEndpoint; i++) {
+            int endRun = breaker.getLevelRunLimit(i, secondEndpoint);
+            TextHitInfo hit1 = TextHitInfo.leading(i);
+            TextHitInfo hit2 = TextHitInfo.trailing(endRun-1);
+
+            Line2D caret1 = getCaretShape(hit1, layout, false, true, bounds);
+            Line2D caret2 = getCaretShape(hit2, layout, false, true, bounds);
+
+            res.append(connectCarets(caret1, caret2), false);
+
+            i = endRun;
+        }
+
+        return res;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/CommonGlyphVector.java b/awt/org/apache/harmony/awt/gl/font/CommonGlyphVector.java
new file mode 100644
index 0000000..4040a60
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/CommonGlyphVector.java
@@ -0,0 +1,954 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Font;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * GlyphVector implementation
+ */
+public class CommonGlyphVector extends GlyphVector {
+
+    // array of transforms of glyphs in GlyphVector
+    protected AffineTransform[] glsTransforms;
+
+    // array of chars defined in constructor
+    public char[] charVector;
+
+    // array of Glyph objects, that describe information about glyphs
+    public Glyph[] vector;
+
+    // array of default positions of glyphs in GlyphVector
+    // without applying GlyphVector's transform
+    float[] defaultPositions;
+
+    // array of logical positions of glyphs in GlyphVector
+
+    float[] logicalPositions;
+
+    // array of visual (real) positions of glyphs in GlyphVector
+    public float[] visualPositions;
+
+    // FontRenderContext for this vector.
+    protected FontRenderContext vectorFRC;
+
+    // layout flags mask
+    protected int layoutFlags = 0;
+
+    // array of cached glyph outlines 
+    protected Shape[] gvShapes;
+
+    FontPeerImpl peer;
+
+    // font corresponding to the GlyphVector 
+    Font font;
+
+    // ascent of the font
+    float ascent;
+
+    // height of the font
+    float height;
+    
+    // leading of the font
+    float leading;
+    
+    // descent of the font
+    float descent;
+
+    // transform of the GlyphVector
+    AffineTransform transform;
+
+    /**
+     * Creates new CommonGlyphVector object from the specified parameters.
+     * 
+     * @param chars an array of chars
+     * @param frc FontRenderContext object
+     * @param fnt Font object
+     * @param flags layout flags
+     */
+    @SuppressWarnings("deprecation")
+    public CommonGlyphVector(char[] chars, FontRenderContext frc, Font fnt,
+            int flags) {
+        int len = chars.length;
+
+        this.font = fnt;
+        this.transform = fnt.getTransform();
+        this.peer = (FontPeerImpl) fnt.getPeer();
+
+        gvShapes = new Shape[len];
+
+        // !! As pointed in API documentation for the 
+        // getGlyphPosisitions(int index,int numEntries, float[] positionReturn) 
+        // and getGlyphPosition(int index) methods, if the index is equals to 
+        // the number of glyphs the position after the last glyph must be 
+        // returned, thus there are n+1 positions and last (n+1) position 
+        // points to the end of GlyphVector.
+
+        logicalPositions = new float[(len+1)<<1];
+        visualPositions = new float[(len+1)<<1];
+        defaultPositions = new float[(len+1)<<1];
+
+        glsTransforms = new AffineTransform[len];
+
+        this.charVector = chars;
+        this.vectorFRC = frc;
+        //LineMetricsImpl lmImpl = (LineMetricsImpl)peer.getLineMetrics();
+
+        LineMetricsImpl lmImpl = (LineMetricsImpl)fnt.getLineMetrics(String.valueOf(chars), frc);
+
+        this.ascent = lmImpl.getAscent();
+        this.height = lmImpl.getHeight();
+        this.leading = lmImpl.getLeading();
+        this.descent = lmImpl.getDescent();
+        this.layoutFlags = flags;
+
+        if ((flags & Font.LAYOUT_RIGHT_TO_LEFT) != 0){
+            char vector[] = new char[len];
+            for(int i=0; i < len; i++){
+                vector[i] = chars[len-i-1];
+            }
+            this.vector = peer.getGlyphs(vector);
+
+        } else {
+            this.vector = peer.getGlyphs(chars);
+        }
+
+        this.glsTransforms = new AffineTransform[len];
+
+        setDefaultPositions();
+        performDefaultLayout();
+    }
+
+    /**
+     * Creates new CommonGlyphVector object from the specified parameters. 
+     * Layout flags set to default.
+     * 
+     * @param chars an array of chars
+     * @param frc FontRenderContext object
+     * @param fnt Font object
+     */
+    public CommonGlyphVector(char[] chars, FontRenderContext frc, Font fnt) {
+        this(chars, frc, fnt, 0);
+    }
+
+    /**
+     * Creates new CommonGlyphVector object from the specified parameters. 
+     * Layout flags set to default.
+     * 
+     * @param str specified string
+     * @param frc FontRenderContext object
+     * @param fnt Font object
+     */
+    public CommonGlyphVector(String str, FontRenderContext frc, Font fnt) {
+        this(str.toCharArray(), frc, fnt, 0);
+    }
+
+    /**
+     * Creates new CommonGlyphVector object from the specified parameters.
+     * 
+     * @param str specified string
+     * @param frc FontRenderContext object
+     * @param fnt Font object
+     * @param flags layout flags
+     */
+    public CommonGlyphVector(String str, FontRenderContext frc, Font fnt, int flags) {
+        this(str.toCharArray(), frc, fnt, flags);
+    }
+
+    /**
+     * Set array of logical positions of the glyphs to
+     * default with their default advances and height.
+     */
+    void setDefaultPositions(){
+        int len = getNumGlyphs();
+
+        // First [x,y] is set into [0,0] position
+        // for this reason start index is 1
+        for (int i=1; i <= len; i++ ){
+                int idx = i << 1;
+                float advanceX = vector[i-1].getGlyphPointMetrics().getAdvanceX();
+                float advanceY = vector[i-1].getGlyphPointMetrics().getAdvanceY();
+
+                defaultPositions[idx] = defaultPositions[idx-2] + advanceX;
+                defaultPositions[idx+1] = defaultPositions[idx-1] + advanceY;
+
+        }
+        transform.transform(defaultPositions, 0, logicalPositions, 0, getNumGlyphs()+1);
+
+    }
+
+    /**
+     * Returnes the pixel bounds of this GlyphVector rendered at the 
+     * specified x,y location with the given FontRenderContext.
+     *  
+     * @param frc a FontRenderContext that is used
+     * @param x specified x coordinate value
+     * @param y specified y coordinate value
+     * @return a Rectangle that bounds pixels of this GlyphVector
+     */
+    @Override
+    public Rectangle getPixelBounds(FontRenderContext frc, float x, float y) {
+
+        double xM, yM, xm, ym;
+
+        double minX = 0;
+        double minY = 0;
+        double maxX = 0;
+        double maxY = 0;
+
+        for (int i = 0; i < this.getNumGlyphs(); i++) {
+            Rectangle glyphBounds = this.getGlyphPixelBounds(i, frc, 0, 0);
+            xm = glyphBounds.getMinX();
+            ym = glyphBounds.getMinY();
+            xM = glyphBounds.getMaxX();
+            yM = glyphBounds.getMaxY();
+
+            if (i == 0) {
+                minX = xm;
+                minY = ym;
+                maxX = xM;
+                maxY = yM;
+            }
+
+            if (minX > xm) {
+                minX = xm;
+            }
+            if (minY > ym) {
+                minY = ym;
+            }
+            if (maxX < xM) {
+                maxX = xM;
+            }
+            if (maxY < yM) {
+                maxY = yM;
+            }
+        }
+        return new Rectangle((int)(minX + x), (int)(minY + y), (int)(maxX - minX), (int)(maxY - minY));
+
+    }
+
+    /**
+     * Returns the visual bounds of this GlyphVector.
+     * The visual bounds is the bounds of the total outline of 
+     * this GlyphVector.
+     * @return a Rectangle2D that id the visual bounds of this GlyphVector
+     */
+    @Override
+    public Rectangle2D getVisualBounds() {
+        float xM, yM, xm, ym;
+        float minX = 0;
+        float minY = 0;
+        float maxX = 0;
+        float maxY = 0;
+        boolean firstIteration = true;
+
+        for (int i = 0; i < this.getNumGlyphs(); i++) {
+            Rectangle2D bounds = this.getGlyphVisualBounds(i).getBounds2D();
+            if (bounds.getWidth() == 0){
+                continue;
+            }
+            xm = (float)bounds.getX();
+            ym = (float)bounds.getY();
+
+            xM = (float)(xm + bounds.getWidth());
+
+            yM = ym + (float) bounds.getHeight();
+
+            if (firstIteration) {
+                minX = xm;
+                minY = ym;
+                maxX = xM;
+                maxY = yM;
+                firstIteration = false;
+            } else {
+                if (minX > xm) {
+                    minX = xm;
+                }
+                if (minY > ym) {
+                    minY = ym;
+                }
+                if (maxX < xM) {
+                    maxX = xM;
+                }
+                if (maxY < yM) {
+                    maxY = yM;
+                }
+
+            }
+        }
+
+        return (this.getNumGlyphs() != 0) ? new Rectangle2D.Float(minX, minY,
+                (maxX - minX), (maxY - minY)) : null;
+    }
+
+    /**
+     * Sets new position to the specified glyph.
+     */
+    @Override
+    public void setGlyphPosition(int glyphIndex, Point2D newPos) {
+        if ((glyphIndex > vector.length) || (glyphIndex < 0)) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        float x = (float)newPos.getX();
+        float y = (float)newPos.getY();
+        int index = glyphIndex << 1;
+
+        if ((x != visualPositions[index]) || (y != visualPositions[index + 1])){
+            visualPositions[index] = x;
+            visualPositions[index+1] = y;
+            layoutFlags = layoutFlags | FLAG_HAS_POSITION_ADJUSTMENTS;
+        }
+
+    }
+
+    /**
+     * Returns the position of the specified glyph relative to the origin of
+     * this GlyphVector
+     * @return a Point2D that the origin of the glyph with specified index
+     */
+    @Override
+    public Point2D getGlyphPosition(int glyphIndex) {
+        if ((glyphIndex > vector.length) || (glyphIndex < 0)) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        int index = glyphIndex << 1;
+        Point2D pos = new Point2D.Float(visualPositions[index], visualPositions[index+1]);
+
+        // For last position we don't have to transform !!
+        if(glyphIndex==vector.length){
+            return pos;
+        }
+
+        AffineTransform at = getGlyphTransform(glyphIndex);
+        if ((at == null) || (at.isIdentity())){
+            return pos;
+        }
+
+        pos.setLocation(pos.getX() + at.getTranslateX(), pos.getY() + at.getTranslateY());
+
+        return pos;
+    }
+
+    /**
+     * Sets new transform to the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     * @param trans AffineTransform of the glyph with specified index
+     */
+    @Override
+    public void setGlyphTransform(int glyphIndex, AffineTransform trans) {
+        if ((glyphIndex >= vector.length) || (glyphIndex < 0)) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+
+        if ((trans == null) || (trans.isIdentity())) {
+            glsTransforms[glyphIndex] = null;
+        } else {
+            glsTransforms[glyphIndex] = new AffineTransform(trans);
+            layoutFlags = layoutFlags | FLAG_HAS_TRANSFORMS;
+        }
+    }
+
+    /**
+     * Returns the affine transform of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     * @return an AffineTransform of the glyph with specified index
+     */
+    @Override
+    public AffineTransform getGlyphTransform(int glyphIndex) {
+        if ((glyphIndex >= this.vector.length) || (glyphIndex < 0)) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        return this.glsTransforms[glyphIndex];
+    }
+
+    /**
+     * Returns the metrics of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    @Override
+    public GlyphMetrics getGlyphMetrics(int glyphIndex) {
+
+        if ((glyphIndex < 0) || ((glyphIndex) >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        // TODO: is there a sence in GlyphMetrics
+        // if certain glyph or Font has a transform??
+        return this.vector[glyphIndex].getGlyphMetrics();
+    }
+
+    /**
+     * Returns a justification information for the glyph with specified glyph 
+     * index.
+     * @param glyphIndex index of a glyph which GlyphJustificationInfo is to be 
+     * received   
+     * @return a GlyphJustificationInfo object that contains glyph justification 
+     * properties of the specified glyph
+     */
+    @Override
+    public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex) {
+        // TODO : Find out the source of Justification info
+        if (true) {
+            throw new RuntimeException("Method is not implemented"); //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * Returns the FontRenderContext parameter of this GlyphVector.
+     */
+    @Override
+    public FontRenderContext getFontRenderContext() {
+        return this.vectorFRC;
+    }
+
+    /**
+     * Returns the visual bounds of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    @Override
+    public Shape getGlyphVisualBounds(int glyphIndex) {
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+
+        int idx  = glyphIndex << 1;
+
+        AffineTransform fontTransform = this.transform;
+        double xOffs = fontTransform.getTranslateX();
+        double yOffs = fontTransform.getTranslateY();
+
+        if (vector[glyphIndex].getWidth() == 0){
+            return new Rectangle2D.Float((float)xOffs, (float)yOffs, 0, 0);
+        }
+
+        AffineTransform at = AffineTransform.getTranslateInstance(xOffs, yOffs);
+        AffineTransform glyphTransform = getGlyphTransform(glyphIndex);
+
+        if (transform.isIdentity() && ((glyphTransform == null) || glyphTransform.isIdentity())){
+            Rectangle2D blackBox = vector[glyphIndex].getGlyphMetrics().getBounds2D();
+            at.translate(visualPositions[idx], visualPositions[idx+1]);
+            return(at.createTransformedShape(blackBox));
+        }
+
+        GeneralPath shape = (GeneralPath)this.getGlyphOutline(glyphIndex);
+        shape.transform(at);
+        return shape.getBounds2D();
+    }
+
+    /**
+     * Returnes the pixel bounds of the specified glyph within GlyphVector 
+     * rendered at the specified x,y location.
+     *  
+     * @param glyphIndex index of the glyph
+     * @param frc a FontRenderContext that is used
+     * @param x specified x coordinate value
+     * @param y specified y coordinate value
+     * @return a Rectangle that bounds pixels of the specified glyph
+     */
+    @Override
+    public Rectangle getGlyphPixelBounds(int glyphIndex, FontRenderContext frc,
+            float x, float y) {
+        // TODO : need to be implemented with FontRenderContext
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+
+        int idx  = glyphIndex << 1;
+
+        if (vector[glyphIndex].getWidth() == 0){
+            AffineTransform fontTransform = this.transform;
+            double xOffs = x + visualPositions[idx] + fontTransform.getTranslateX();
+            double yOffs = y + visualPositions[idx+1] + fontTransform.getTranslateY();
+            return new Rectangle((int)xOffs, (int)yOffs, 0, 0);
+        }
+
+        GeneralPath shape = (GeneralPath)this.getGlyphOutline(glyphIndex);
+
+        AffineTransform at = AffineTransform.getTranslateInstance(x, y);
+
+        if (frc != null){
+            at.concatenate(frc.getTransform());
+        }
+
+        shape.transform(at);
+
+        Rectangle bounds = shape.getBounds();
+        return new Rectangle((int)bounds.getX(), (int)bounds.getY(),
+                            (int)bounds.getWidth()-1, (int)bounds.getHeight()-1);
+        }
+
+    /**
+     * Returns a Shape that encloses specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    @Override
+    public Shape getGlyphOutline(int glyphIndex) {
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+
+        if (gvShapes[glyphIndex] == null) {
+            gvShapes[glyphIndex] = vector[glyphIndex].getShape();
+        }
+
+        GeneralPath gp = (GeneralPath)((GeneralPath)gvShapes[glyphIndex]).clone();
+
+        /* Applying GlyphVector font transform */
+        AffineTransform at = (AffineTransform)this.transform.clone();
+
+        /* Applying Glyph transform */
+        AffineTransform glyphAT = getGlyphTransform(glyphIndex);
+        if (glyphAT != null){
+            at.preConcatenate(glyphAT);
+        }
+
+        int idx  = glyphIndex << 1;
+
+        gp.transform(at);
+        gp.transform(AffineTransform.getTranslateInstance(visualPositions[idx], visualPositions[idx+1]));
+        return gp;
+    }
+
+
+    /**
+     * Returns a Shape that is the outline representation of this GlyphVector 
+     * rendered at the specified x,y coordinates.
+     * 
+     * @param x specified x coordinate value
+     * @param y specified y coordinate value
+     * @return a Shape object that is the outline of this GlyphVector
+     * at the specified coordinates.
+     */
+    @Override
+    public Shape getOutline(float x, float y) {
+        GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
+        for (int i = 0; i < this.vector.length; i++) {
+            GeneralPath outline = (GeneralPath)getGlyphOutline(i);
+
+            /* Applying translation to actual visual bounds */
+            outline.transform(AffineTransform.getTranslateInstance(x, y));
+            gp.append(outline, false);
+        }
+
+        return gp;
+    }
+
+    /**
+     * Returns a Shape that is the outline representation of this GlyphVector.
+     * 
+     * @return a Shape object that is the outline of this GlyphVector
+     */
+    @Override
+    public Shape getOutline() {
+        return this.getOutline(0, 0);
+    }
+
+    /**
+     * Returns an array of glyphcodes for the specified glyphs.
+     * 
+     * @param beginGlyphIndex the start index
+     * @param numEntries the number of glyph codes to get
+     * @param codeReturn the array that receives glyph codes' values
+     * @return an array that receives glyph codes' values
+     */
+    @Override
+    public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
+            int[] codeReturn) {
+
+        if ((beginGlyphIndex < 0) || ((numEntries + beginGlyphIndex) > this.getNumGlyphs())) {
+            // awt.44=beginGlyphIndex is out of vector's range
+            throw new IndexOutOfBoundsException(Messages.getString("awt.44")); //$NON-NLS-1$
+        }
+
+        if (numEntries < 0) {
+            // awt.45=numEntries is out of vector's range
+            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
+        }
+
+        if (codeReturn == null) {
+            codeReturn = new int[numEntries];
+        }
+
+        for (int i = beginGlyphIndex; i < beginGlyphIndex + numEntries; i++) {
+            codeReturn[i-beginGlyphIndex] = this.vector[i].getGlyphCode();
+        }
+
+        return codeReturn;
+    }
+
+    /**
+     * Returns an array of numEntries character indices for the specified glyphs.
+     * 
+     * @param beginGlyphIndex the start index
+     * @param numEntries the number of glyph codes to get
+     * @param codeReturn the array that receives glyph codes' values
+     * @return an array that receives glyph char indices
+     */
+    @Override
+    public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries,
+            int[] codeReturn) {
+        if ((beginGlyphIndex < 0) || (beginGlyphIndex >= this.getNumGlyphs())) {
+            // awt.44=beginGlyphIndex is out of vector's range
+            throw new IllegalArgumentException(Messages.getString("awt.44")); //$NON-NLS-1$
+        }
+
+        if ((numEntries < 0)
+                || ((numEntries + beginGlyphIndex) > this.getNumGlyphs())) {
+            // awt.45=numEntries is out of vector's range
+            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
+        }
+
+        if (codeReturn == null) {
+            codeReturn = new int[numEntries];
+        }
+
+        for (int i = 0; i < numEntries; i++) {
+            codeReturn[i] = this.getGlyphCharIndex(i + beginGlyphIndex);
+        }
+        return codeReturn;
+    }
+
+    /**
+     * Returns an array of numEntries glyphs positions from beginGlyphIndex
+     * glyph in Glyph Vector.
+     * 
+     * @param beginGlyphIndex the start index
+     * @param numEntries the number of glyph codes to get
+     * @param positionReturn the array that receives glyphs' positions
+     * @return an array of floats that receives glyph char indices
+     */
+    @Override
+    public float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
+            float[] positionReturn) {
+
+        int len = (this.getNumGlyphs()+1) << 1;
+        beginGlyphIndex *= 2;
+        numEntries *= 2;
+
+        if ((beginGlyphIndex < 0) || ((numEntries + beginGlyphIndex) > len)) {
+            // awt.44=beginGlyphIndex is out of vector's range
+            throw new IndexOutOfBoundsException(Messages.getString("awt.44")); //$NON-NLS-1$
+        }
+
+        if (numEntries < 0) {
+            // awt.45=numEntries is out of vector's range
+            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
+        }
+
+        if (positionReturn == null) {
+            positionReturn = new float[numEntries];
+        }
+
+        System.arraycopy(visualPositions, beginGlyphIndex, positionReturn, 0, numEntries);
+
+        return positionReturn;
+    }
+
+    /**
+     * Set numEntries elements of the visualPositions array from beginGlyphIndex
+     * of numEntries glyphs positions from beginGlyphIndex glyph in Glyph Vector.
+     * 
+     * @param beginGlyphIndex the start index
+     * @param numEntries the number of glyph codes to get
+     * @param setPositions the array of positions to set
+     */
+    public void setGlyphPositions(int beginGlyphIndex, int numEntries,
+            float[] setPositions) {
+
+        int len = (this.getNumGlyphs()+1) << 1;
+        beginGlyphIndex *= 2;
+        numEntries *= 2;
+
+        if ((beginGlyphIndex < 0) || ((numEntries + beginGlyphIndex) > len)) {
+            // awt.44=beginGlyphIndex is out of vector's range
+            throw new IndexOutOfBoundsException(Messages.getString("awt.44")); //$NON-NLS-1$
+        }
+
+        if (numEntries < 0) {
+            // awt.45=numEntries is out of vector's range
+            throw new IllegalArgumentException(Messages.getString("awt.45")); //$NON-NLS-1$
+        }
+
+        System.arraycopy(setPositions, 0, visualPositions, beginGlyphIndex, numEntries);
+        layoutFlags = layoutFlags & FLAG_HAS_POSITION_ADJUSTMENTS;
+
+    }
+
+    /**
+     * Set elements of the visualPositions array.
+     * 
+     * @param setPositions the array of positions to set
+     */
+    public void setGlyphPositions(float[] setPositions) {
+
+        int len = (this.getNumGlyphs()+1) << 1;
+        if (len != setPositions.length){
+            // awt.46=length of setPositions array differs from the length of positions array
+            throw new IllegalArgumentException(Messages.getString("awt.46")); //$NON-NLS-1$
+        }
+
+        System.arraycopy(setPositions, 0, visualPositions, 0, len);
+        layoutFlags = layoutFlags & FLAG_HAS_POSITION_ADJUSTMENTS;
+
+    }
+
+
+    /**
+     * Returns glyph code of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    @Override
+    public int getGlyphCode(int glyphIndex) {
+        if (glyphIndex >= this.vector.length || glyphIndex < 0) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        return this.vector[glyphIndex].getGlyphCode();
+    }
+
+    /**
+     * Returns character index of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    @Override
+    public int getGlyphCharIndex(int glyphIndex) {
+
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IllegalArgumentException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+
+        if ((this.layoutFlags & Font.LAYOUT_RIGHT_TO_LEFT) != 0) {
+            return this.charVector.length - glyphIndex - 1;
+        }
+
+        return glyphIndex;
+    }
+
+    /**
+     * Returns a character value of the specified glyph.
+     * 
+     * @param glyphIndex specified index of the glyph
+     */
+    public char getGlyphChar(int glyphIndex) {
+
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())) {
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IllegalArgumentException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        return this.charVector[glyphIndex];
+    }
+
+    /**
+     * Assigns default positions to each glyph in this GlyphVector.
+     */
+    @Override
+    public void performDefaultLayout() {
+
+        System.arraycopy(logicalPositions, 0, visualPositions, 0, logicalPositions.length);
+
+        // Set position changes flag to zero
+        clearLayoutFlags(GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS);
+    }
+
+    /**
+     * Returns the number of glyphs in this Glyph Vector
+     */
+    @Override
+    public int getNumGlyphs() {
+        return vector.length;
+    }
+
+    /**
+     * Returns the logical bounds of this GlyphVector
+     */
+    @Override
+    public Rectangle2D getLogicalBounds(){
+        // XXX: for transforms where an angle between basis vectors is not 90 degrees
+        // Rectanlge2D class doesn't fit as Logical bounds. For this reason we use
+        // only non-transformed bounds!!
+
+        float x = visualPositions[0];
+        float width = visualPositions[visualPositions.length-2];
+
+        double scaleY =  transform.getScaleY();
+
+        Rectangle2D bounds = new Rectangle2D.Float(x, (float)((-this.ascent-this.leading)*scaleY), width, (float)(this.height*scaleY));
+        return bounds;
+    }
+
+
+    /**
+     * Checks whether given GlyphVector equals to this GlyphVector.
+     * @param glyphVector GlyphVector object to compare
+     */
+    @Override
+    public boolean equals(GlyphVector glyphVector){
+        if (glyphVector == this){
+            return true;
+        }
+
+        if (glyphVector != null) {
+
+            if (!(glyphVector.getFontRenderContext().equals(this.vectorFRC) &&
+                      glyphVector.getFont().equals(this.font))){
+                return false;
+            }
+
+            try {
+                boolean eq = true;
+                for (int i = 0; i < getNumGlyphs(); i++) {
+
+                    int idx = i*2;
+                    eq = (((CommonGlyphVector)glyphVector).visualPositions[idx] == this.visualPositions[idx]) &&
+                        (((CommonGlyphVector)glyphVector).visualPositions[idx+1] == this.visualPositions[idx+1]) &&
+                        (glyphVector.getGlyphCharIndex(i) == this.getGlyphCharIndex(i));
+
+                    if (eq){
+                        AffineTransform trans = glyphVector.getGlyphTransform(i);
+                        if (trans == null){
+                            eq = (this.glsTransforms[i] == null);
+                        }else{
+                            eq = this.glsTransforms[i].equals(trans);
+                        }
+                    }
+
+                    if (!eq){
+                        return false;
+                    }
+                }
+
+                return  eq;
+            } catch (ClassCastException e) {
+            }
+        }
+
+        return false;
+    }
+
+
+    /**
+     * Returns flags describing the state of the GlyphVector.
+     */
+    @Override
+    public int getLayoutFlags() {
+        return layoutFlags;
+    }
+
+    /**
+     * Returns char with the specified index.
+     * 
+     * @param index specified index of the char
+     * 
+     */
+    public char getChar(int index) {
+        return this.charVector[index];
+
+    }
+
+    /**
+     * Clear desired flags in layout flags describing the state. 
+     * 
+     * @param clearFlags flags mask to clear 
+     */
+    
+    private void clearLayoutFlags(int clearFlags){
+        layoutFlags &= ~clearFlags;
+    }
+
+    /**
+     * Returns the logical bounds of the specified glyph within this CommonGlyphVector.
+     * 
+     * @param glyphIndex index of the glyph to get it's logical bounds
+     * @return logical bounds of the specified glyph
+     */
+    @Override
+    public Shape getGlyphLogicalBounds(int glyphIndex){
+        if ((glyphIndex < 0) || (glyphIndex >= this.getNumGlyphs())){
+            // awt.43=glyphIndex is out of vector's limits
+            throw new IndexOutOfBoundsException(Messages.getString("awt.43")); //$NON-NLS-1$
+        }
+        Glyph glyph = this.vector[glyphIndex];
+
+        float x0 = visualPositions[glyphIndex*2];
+        float y0 = visualPositions[glyphIndex*2+1];
+        float advanceX = glyph.getGlyphPointMetrics().getAdvanceX();
+
+        GeneralPath gp = new GeneralPath();
+        gp.moveTo(0, -ascent - leading);
+        gp.lineTo(advanceX ,-ascent - leading);
+        gp.lineTo(advanceX, descent);
+        gp.lineTo(0, descent);
+        gp.lineTo(0, -ascent - leading);
+        gp.closePath();
+
+        /* Applying GlyphVector font transform */
+        AffineTransform at = (AffineTransform)this.transform.clone();
+
+        /* Applying Glyph transform */
+        AffineTransform glyphTransform = getGlyphTransform(glyphIndex);
+        if (glyphTransform != null){
+            at.concatenate(glyphTransform);
+        }
+
+        /* Applying translation to actual visual bounds */
+        at.preConcatenate(AffineTransform.getTranslateInstance(x0, y0));
+        gp.transform(at);
+        return gp;
+    }
+
+    /**
+     * Returns the Font parameter of this GlyphVector
+     */
+    @Override
+    public Font getFont(){
+        return this.font;
+    }
+
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/font/CompositeFont.java b/awt/org/apache/harmony/awt/gl/font/CompositeFont.java
new file mode 100644
index 0000000..70cb334
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/CompositeFont.java
@@ -0,0 +1,486 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.harmony.awt.gl.font.FontPeerImpl;
+import org.apache.harmony.awt.gl.font.FontProperty;
+
+/**
+ * CompositeFont class is the implementation of logical font classes. 
+ * Every logical font consists of several physical fonts that described 
+ * in font.properties file according to the face name of this logical font.
+ */
+public class CompositeFont extends FontPeerImpl{
+    
+    // a number of physical fonts that CompositeFont consist of 
+    int numFonts;
+
+    // font family name
+    String family;
+
+    // font face name
+    String face;
+
+    String[] fontNames;
+    
+    // an array of font properties applicable to this CompositeFont
+    FontProperty[] fontProperties;
+    
+    // an array of font peers applicable to this CompositeFont
+    public FontPeerImpl[] fPhysicalFonts;
+    
+    // missing glyph code field
+    int missingGlyphCode = -1;
+    
+    // line metrics of this font
+    LineMetricsImpl nlm = null;
+    
+    // cached num glyphs parameter of this font that is the sum of num glyphs of 
+    // font peers composing this font
+    int cachedNumGlyphs = -1;
+    /**
+     * Creates CompositeFont object that is corresponding to the specified logical 
+     * family name.
+     * 
+     * @param familyName logical family name CompositeFont is to be created from
+     * @param faceName logical face name CompositeFont is to be created from
+     * @param _style style of the CompositeFont to be created
+     * @param _size size of the CompositeFont to be created 
+     * @param fProperties an array of FontProperties describing physical fonts - 
+     * parts of logical font
+     * @param physFonts an array of physical font peers related to the CompositeFont
+     * to be created
+     */
+    public CompositeFont(String familyName, String faceName, int _style, int _size, FontProperty[] fProperties, FontPeerImpl[] physFonts){
+        this.size = _size;
+        this.name = faceName;
+        this.family = familyName;
+        this.style = _style;
+        this.face = faceName;
+        this.psName = faceName;
+        this.fontProperties = fProperties;// !! Supposed that fProperties parameter != null
+        fPhysicalFonts = physFonts;
+        numFonts = fPhysicalFonts.length; 
+        setDefaultLineMetrics("", null); //$NON-NLS-1$
+        this.uniformLM = false;
+    }
+
+    /**
+     * Returns the index of the FontPeer in array of physical fonts that is applicable 
+     * for the given character. This font has to have the highest priority among fonts
+     * that can display this character and don't have exclusion range covering 
+     * specified character. If there is no desired fonts -1 is returned.
+     * 
+     * @param chr specified character
+     * @return index of the font from the array of physical fonts that will be used 
+     * during processing of the specified character. 
+     */
+    public int getCharFontIndex(char chr){
+        for (int i = 0; i < numFonts; i++){
+            if (fontProperties[i].isCharExcluded(chr)){
+                continue;
+            }
+            if (fPhysicalFonts[i].canDisplay(chr)){
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns the index of the FontPeer in array of physical fonts that is applicable 
+     * for the given character. This font has to have the highest priority among fonts
+     * that can display this character and don't have exclusion range covering 
+     * specified character. If there is no desired fonts default value is returned.
+     * 
+     * @param chr specified character
+     * @param defaultValue default index that is returned if the necessary font couldn't be found.
+     * @return index of the font from the array of physical fonts that will be used 
+     * during processing of the specified character. 
+     */
+     public int getCharFontIndex(char chr, int defaultValue){
+        for (int i = 0; i < numFonts; i++){
+            if (fontProperties[i].isCharExcluded(chr)){
+                continue;
+            }
+            if (fPhysicalFonts[i].canDisplay(chr)){
+                return i;
+            }
+        }
+
+        return defaultValue;
+    }
+
+    /**
+     * Returns true if one of the physical fonts composing this font CompositeFont 
+     * can display specified character.
+     *   
+     * @param chr specified character
+     */
+    @Override
+    public boolean canDisplay(char chr){
+        return (getCharFontIndex(chr) != -1);
+    }
+
+    /**
+     * Returns logical ascent (in pixels)
+     */
+    @Override
+    public int getAscent(){
+        return nlm.getLogicalAscent();
+    }
+
+    /**
+     * Returns LineMetrics instance scaled according to the specified transform.  
+     * 
+     * @param str specified String 
+     * @param frc specified FontRenderContext 
+     * @param at specified AffineTransform
+     */
+     @Override
+    public LineMetrics getLineMetrics(String str, FontRenderContext frc , AffineTransform at){
+        LineMetricsImpl lm = (LineMetricsImpl)(this.nlm.clone());
+        lm.setNumChars(str.length());
+
+        if ((at != null) && (!at.isIdentity())){
+            lm.scale((float)at.getScaleX(), (float)at.getScaleY());
+        }
+
+        return lm;
+    }
+
+    /**
+     * Returns cached LineMetrics instance for the null string or creates it if
+     * it wasn't cached yet.
+     */
+    @Override
+    public LineMetrics getLineMetrics(){
+        if (nlm == null){
+            setDefaultLineMetrics("", null); //$NON-NLS-1$
+        }
+
+        return this.nlm;
+    }
+
+    /**
+     * Creates LineMetrics instance and set cached LineMetrics field to it.
+     * Created LineMetrics has maximum values of the idividual metrics of all
+     * composing physical fonts. If there is only one physical font - it's 
+     * LineMetrics object is returned.
+     * 
+     * @param str specified String 
+     * @param frc specified FontRenderContext 
+     */
+    private void setDefaultLineMetrics(String str, FontRenderContext frc){
+        LineMetrics lm = fPhysicalFonts[0].getLineMetrics(str, frc, null);
+        float maxCharWidth = (float)fPhysicalFonts[0].getMaxCharBounds(frc).getWidth();
+
+        if (numFonts == 1) {
+            this.nlm = (LineMetricsImpl)lm;
+            return;
+        }
+
+        float[] baselineOffsets = lm.getBaselineOffsets();
+        int numChars = str.length();
+
+        // XXX: default value - common for all Fonts
+        int baseLineIndex = lm.getBaselineIndex();
+
+        float maxUnderlineThickness = lm.getUnderlineThickness();
+        float maxUnderlineOffset = lm.getUnderlineOffset();
+        float maxStrikethroughThickness = lm.getStrikethroughThickness();
+        float minStrikethroughOffset = lm.getStrikethroughOffset();
+        float maxLeading = lm.getLeading();  // External leading
+        float maxHeight = lm.getHeight();   // Height of the font ( == (ascent + descent + leading))
+        float maxAscent = lm.getAscent();   // Ascent of the font
+        float maxDescent = lm.getDescent(); // Descent of the font
+
+        for (int i = 1; i < numFonts; i++){
+            lm = fPhysicalFonts[i].getLineMetrics(str, frc, null);
+            if (maxUnderlineThickness < lm.getUnderlineThickness()){
+                maxUnderlineThickness = lm.getUnderlineThickness();
+            }
+
+            if (maxUnderlineOffset < lm.getUnderlineOffset()){
+                maxUnderlineOffset = lm.getUnderlineOffset();
+            }
+
+            if (maxStrikethroughThickness < lm.getStrikethroughThickness()){
+                maxStrikethroughThickness = lm.getStrikethroughThickness();
+            }
+
+            if (minStrikethroughOffset > lm.getStrikethroughOffset()){
+                minStrikethroughOffset = lm.getStrikethroughOffset();
+            }
+
+            if (maxLeading < lm.getLeading()){
+                maxLeading = lm.getLeading();
+            }
+
+            if (maxAscent < lm.getAscent()){
+                maxAscent = lm.getAscent();
+            }
+
+            if (maxDescent < lm.getDescent()){
+                maxDescent = lm.getDescent();
+            }
+
+            float width = (float)fPhysicalFonts[i].getMaxCharBounds(frc).getWidth();
+            if(maxCharWidth < width){
+                maxCharWidth = width;
+            }
+            for (int j =0; j < baselineOffsets.length; j++){
+                float[] offsets = lm.getBaselineOffsets();
+                if (baselineOffsets[j] > offsets[j]){
+                    baselineOffsets[j] = offsets[j];
+                }
+            }
+
+        }
+        maxHeight = maxAscent + maxDescent + maxLeading;
+
+        this.nlm =  new LineMetricsImpl(
+                numChars,
+                baseLineIndex,
+                baselineOffsets,
+                maxUnderlineThickness,
+                maxUnderlineOffset,
+                maxStrikethroughThickness,
+                minStrikethroughOffset,
+                maxLeading,
+                maxHeight,
+                maxAscent,
+                maxDescent,
+                maxCharWidth);
+
+    }
+
+    /**
+     * Returns the number of glyphs in this CompositeFont object.
+     */
+    @Override
+    public int getNumGlyphs(){
+        if (this.cachedNumGlyphs == -1){
+
+            this.cachedNumGlyphs = 0;
+
+            for (int i = 0; i < numFonts; i++){
+                this.cachedNumGlyphs += fPhysicalFonts[i].getNumGlyphs();
+            }
+        }
+
+        return this.cachedNumGlyphs;
+    }
+
+    /**
+     * Returns the italic angle of this object.
+     */
+    @Override
+    public float getItalicAngle(){
+        // !! only first physical font used to get this value
+        return fPhysicalFonts[0].getItalicAngle();
+    }
+
+    /**
+     * Returns rectangle that bounds the specified string in terms of composite line metrics.
+     * 
+     * @param chars an array of chars
+     * @param start the initial offset in array of chars
+     * @param end the end offset in array of chars
+     * @param frc specified FontRenderContext
+     */
+    public Rectangle2D getStringBounds(char[] chars, int start, int end, FontRenderContext frc){
+
+        LineMetrics lm = getLineMetrics();
+        float minY = -lm.getAscent();
+        float minX = 0;
+        float height = lm.getHeight();
+        float width = 0;
+
+        for (int i = start; i < end; i++){
+            width += charWidth(chars[i]);
+        }
+
+        Rectangle2D rect2D = new Rectangle2D.Float(minX, minY, width, height);
+        return rect2D;
+
+    }
+
+    /**
+     * Returns maximum rectangle that encloses all maximum char bounds of 
+     * physical fonts composing this CompositeFont.
+     *  
+     * @param frc specified FontRenderContext
+     */
+    @Override
+    public Rectangle2D getMaxCharBounds(FontRenderContext frc){
+
+        Rectangle2D rect2D = fPhysicalFonts[0].getMaxCharBounds(frc);
+        float minY = (float)rect2D.getY();
+        float maxWidth = (float)rect2D.getWidth();
+        float maxHeight = (float)rect2D.getHeight();
+        if (numFonts == 1){
+            return rect2D;
+        }
+
+        for (int i = 1; i < numFonts; i++){
+            if (fPhysicalFonts[i] != null){
+                rect2D = fPhysicalFonts[i].getMaxCharBounds(frc);
+                float y = (float)rect2D.getY();
+                float mWidth = (float)rect2D.getWidth();
+                float mHeight = (float)rect2D.getHeight();
+                if (y < minY){
+                    minY = y;
+                }
+                if (mWidth > maxWidth){
+                    maxHeight = mWidth;
+                }
+                
+                if (mHeight > maxHeight){
+                    maxHeight = mHeight;
+                }
+            }
+        }
+
+        rect2D = new Rectangle2D.Float(0, minY, maxWidth, maxHeight);
+
+        return rect2D;
+    }
+
+    /**
+     * Returns font name.
+     */
+    @Override
+    public String getFontName(){
+        return face;
+    }
+
+    /**
+     * Returns font postscript name.
+     */
+    @Override
+    public String getPSName(){
+        return psName;
+    }
+
+    /**
+     * Returns font family name.
+     */
+    @Override
+    public String getFamily(){
+        return family;
+    }
+
+    /**
+     * Returns the code of the missing glyph.
+     */
+    @Override
+    public int getMissingGlyphCode(){
+        // !! only first physical font used to get this value
+        return fPhysicalFonts[0].getMissingGlyphCode();
+    }
+
+    /**
+     * Returns Glyph object corresponding to the specified character.
+     * 
+     * @param ch specified char
+     */
+    @Override
+    public Glyph getGlyph(char ch){
+        for (int i = 0; i < numFonts; i++){
+            if (fontProperties[i].isCharExcluded(ch)){
+                    continue;
+            }
+            
+            /* Control symbols considered to be supported by the font peer */
+            if ((ch < 0x20) || fPhysicalFonts[i].canDisplay(ch)){
+                return fPhysicalFonts[i].getGlyph(ch);
+            }
+        }
+        return getDefaultGlyph();
+    }
+
+    /**
+     * Returns width of the char with specified index.
+     * 
+     * @param ind specified index of the character 
+     */
+    @Override
+    public int charWidth(int ind){
+        return charWidth((char)ind);
+    }
+
+    /**
+     * Returns width of the specified char.
+     * 
+     * @param c specified character 
+     */
+    @Override
+    public int charWidth(char c){
+        Glyph gl = this.getGlyph(c);
+        return (int)gl.getGlyphPointMetrics().getAdvanceX();
+    }
+
+    /**
+     * Returns debug information about this class.
+     */
+    @Override
+    public String toString(){
+    return new String(this.getClass().getName() +
+            "[name=" + this.name + //$NON-NLS-1$
+            ",style="+ this.style + //$NON-NLS-1$
+            ",fps=" + this.fontProperties + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Returns Glyph object corresponding to the default glyph.
+     */
+    @Override
+    public Glyph getDefaultGlyph(){
+        // !! only first physical font used to get this value
+        return fPhysicalFonts[0].getDefaultGlyph();
+    }
+    
+    /**
+     * Returns FontExtraMetrics object with extra metrics
+     * related to this CompositeFont.
+     */
+    @Override
+    public FontExtraMetrics getExtraMetrics(){
+        // Returns FontExtraMetrics instanse of the first physical 
+        // Font from the array of fonts.
+        return fPhysicalFonts[0].getExtraMetrics();
+    }
+
+    /**
+     * Disposes CompositeFont object's resources.
+     */
+    @Override
+    public void dispose() {
+        // Nothing to dispose
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontExtraMetrics.java b/awt/org/apache/harmony/awt/gl/font/FontExtraMetrics.java
new file mode 100644
index 0000000..047ba6d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontExtraMetrics.java
@@ -0,0 +1,145 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ * 
+ */
+package org.apache.harmony.awt.gl.font;
+
+/**
+ * Extra font metrics: sub/superscripts sizes, offsets, average char width.
+ */
+public class FontExtraMetrics {
+    
+    /* !! Subscript/superscript metrics are undefined for Type1. As a possible 
+     * solution we can use values for Type1, that are proportionate to TrueType
+     * ones:
+     *  SubscriptSizeX == 0.7 * fontSize
+     *  SubscriptSizeY == 0.65 * fontSize
+     *  SubscriptOffsetX == 0;
+     *  SubscriptOffsetY == 0.15 * fontSize;
+     *  SuperscriptSizeX == 0.7 * fontSize
+     *  SuperscriptSizeY == 0.65 * fontSize
+     *  SuperscriptOffsetX == 0;
+     *  SuperscriptOffsetY == 0.45 * fontSize
+     *  
+     */
+    
+    /*
+     * The average width of characters in the font.
+     */
+    private float lAverageCharWidth;
+    
+    /*
+     * Horizontal size for subscripts.
+     */
+    private float lSubscriptSizeX;
+
+    /*
+     * Vertical size for subscripts.
+     */
+    private float lSubscriptSizeY; 
+    
+    /*
+     * Horizontal offset for subscripts, the offset from the character origin 
+     * to the origin of the subscript character.
+     */
+    private float lSubscriptOffsetX; 
+
+    /*
+     * Vertical offset for subscripts, the offset from the character origin 
+     * to the origin of the subscript character.
+     */
+    private float lSubscriptOffsetY;
+    
+    /*
+     * Horizontal size for superscripts.
+     */
+    private float lSuperscriptSizeX; 
+
+    /*
+     * Vertical size for superscripts.
+     */
+    private float lSuperscriptSizeY;
+    
+    /*
+     * Horizontal offset for superscripts, the offset from the character 
+     * base line to the base line of the superscript character.
+     */
+    private float lSuperscriptOffsetX;
+
+    /*
+     * Vertical offset for superscripts, the offset from the character 
+     * base line to the base line of the superscript character.
+     */
+    private float lSuperscriptOffsetY;
+    
+    public FontExtraMetrics(){
+        // default constructor
+    }
+
+    public FontExtraMetrics(float[] metrics){
+        lAverageCharWidth = metrics[0];
+        lSubscriptSizeX = metrics[1];
+        lSubscriptSizeY = metrics[2];
+        lSubscriptOffsetX = metrics[3];
+        lSubscriptOffsetY = metrics[4];
+        lSuperscriptSizeX = metrics[5];
+        lSuperscriptSizeY = metrics[6];
+        lSuperscriptOffsetX = metrics[7];
+        lSuperscriptOffsetY = metrics[8];
+    }
+
+    public float getAverageCharWidth(){
+        return lAverageCharWidth;
+    }
+    
+    public float getSubscriptSizeX(){
+        return lSubscriptSizeX;
+    }
+
+    public float getSubscriptSizeY(){
+        return lSubscriptSizeY;
+    }
+
+    public float getSubscriptOffsetX(){
+        return lSubscriptOffsetX;
+    }
+
+    public float getSubscriptOffsetY(){
+        return lSubscriptOffsetY;
+    }
+
+    public float getSuperscriptSizeX(){
+        return lSuperscriptSizeX;
+    }
+
+    public float getSuperscriptSizeY(){
+        return lSuperscriptSizeY;
+    }
+
+    public float getSuperscriptOffsetX(){
+        return lSuperscriptOffsetX;
+    }
+
+    public float getSuperscriptOffsetY(){
+        return lSuperscriptOffsetY;
+    }
+    
+    
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontFinder.java b/awt/org/apache/harmony/awt/gl/font/FontFinder.java
new file mode 100644
index 0000000..09bcf5c
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontFinder.java
@@ -0,0 +1,121 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Jul 12, 2005
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Font;
+import java.awt.GraphicsEnvironment;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class chooses the default font for the given text.
+ * If it finds the character which current font is unable to display
+ * it starts the next font run and looks for the font which is able to
+ * display the current character. It also caches the font mappings
+ * (index in the array containing all fonts) for the characters,
+ * using that fact that scripts are mainly contiguous in the UTF-16 encoding
+ * and there's a high probability that the upper byte will be the same for the
+ * next character as for the previous. This allows to save the space used for the cache.
+ */
+public class FontFinder {
+    private static final float DEFAULT_FONT_SIZE = 12;
+
+    private static final Font fonts[] =
+            GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
+
+    private static final int NUM_BLOCKS = 256;
+    private static final int BLOCK_SIZE = 256;
+    private static final int INDEX_MASK = 0xFF;
+    private static final int BLOCK_SHIFT = 8;
+
+    // Maps characters into the fonts array
+    private static final int blocks[][] = new int[NUM_BLOCKS][];
+
+    /**
+     * Finds the font which is able to display the given character
+     * and saves the font mapping for this character
+     * @param c - character
+     * @return font
+     */
+    static Font findFontForChar(char c) {
+        int blockNum = c >> BLOCK_SHIFT;
+        int index = c & INDEX_MASK;
+
+        if (blocks[blockNum] == null) {
+            blocks[blockNum] = new int[BLOCK_SIZE];
+        }
+
+        if (blocks[blockNum][index] == 0) {
+            blocks[blockNum][index] = 1;
+
+            for (int i=0; i<fonts.length; i++) {
+                if (fonts[i].canDisplay(c)) {
+                    blocks[blockNum][index] = i+1;
+                    break;
+                }
+            }
+        }
+
+        return getDefaultSizeFont(blocks[blockNum][index]-1);
+    }
+
+    /**
+     * Derives the default size font
+     * @param i - index in the array of all fonts
+     * @return derived font
+     */
+    static Font getDefaultSizeFont(int i) {
+        if (fonts[i].getSize() != DEFAULT_FONT_SIZE) {
+            fonts[i] = fonts[i].deriveFont(DEFAULT_FONT_SIZE);
+        }
+
+        return fonts[i];
+    }
+
+    /**
+     * Assigns default fonts for the given text run.
+     * First three parameters are input, last three are output.
+     * @param text - given text
+     * @param runStart - start of the text run
+     * @param runLimit - end of the text run
+     * @param runStarts - starts of the resulting font runs
+     * @param fonts - mapping of the font run starts to the fonts
+     */
+    static void findFonts(char text[], int runStart, int runLimit, List<Integer> runStarts,
+            Map<Integer, Font> fonts) {
+        Font prevFont = null;
+        Font currFont;
+        for (int i = runStart; i < runLimit; i++) {
+            currFont = findFontForChar(text[i]);
+            if (currFont != prevFont) {
+                prevFont = currFont;
+                Integer idx = new Integer(i);
+                fonts.put(idx, currFont);
+                if (i != runStart) {
+                    runStarts.add(idx);
+                }
+            }
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontManager.java b/awt/org/apache/harmony/awt/gl/font/FontManager.java
new file mode 100644
index 0000000..8354e25
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontManager.java
@@ -0,0 +1,819 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Font;
+import java.awt.peer.FontPeer;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.harmony.awt.gl.CommonGraphics2DFactory;
+import org.apache.harmony.luni.util.NotImplementedException;
+
+
+public abstract class FontManager {
+    
+    //???AWT
+    boolean NOT_IMP = false;
+    
+    /**
+     * array of font families names
+     */
+    public String[] allFamilies;
+
+    public static final String DEFAULT_NAME = "Default"; /* Default font name */ //$NON-NLS-1$
+    public static final String DIALOG_NAME = "Dialog";  /* Dialog font name */ //$NON-NLS-1$
+
+    /**
+     * Set of constants applicable to the TrueType 'name' table.
+     */
+    public static final byte  FAMILY_NAME_ID  = 1;      /* Family name identifier   */
+    public static final byte  FONT_NAME_ID  = 4;        /* Full font name identifier    */
+    public static final byte  POSTSCRIPT_NAME_ID = 6;   /* PostScript name identifier   */
+    public static final short ENGLISH_LANGID = 0x0409;  /* English (United States)language identifier   */
+
+    /**
+     * Set of constants describing font type.
+     */
+    public static final byte  FONT_TYPE_TT  = 4;        /* TrueType type (TRUETYPE_FONTTYPE)    */
+    public static final byte  FONT_TYPE_T1  = 2;        /* Type1 type    (DEVICE_FONTTYPE)      */
+    public static final byte  FONT_TYPE_UNDEF  = 0;     /* Undefined type                       */
+
+    // logical family types (indices in FontManager.LOGICAL_FONT_NAMES)
+    static final int DIALOG = 3;        // FF_SWISS
+    static final int SANSSERIF = 1;     // FF_SWISS
+    static final int DIALOGINPUT = 4;   // FF_MODERN
+    static final int MONOSPACED = 2;    // FF_MODERN
+    static final int SERIF = 0;         // FF_ROMAN
+
+
+    /**
+     * FontProperty related constants. 
+     */
+    public static final String PLATFORM_FONT_NAME = "PlatformFontName"; //$NON-NLS-1$
+    public static final String LOGICAL_FONT_NAME = "LogicalFontName"; //$NON-NLS-1$
+    public static final String COMPONENT_INDEX = "ComponentIndex"; //$NON-NLS-1$
+    public static final String STYLE_INDEX = "StyleIndex"; //$NON-NLS-1$
+
+    public static final String[] FONT_MAPPING_KEYS = {
+            "LogicalFontName.StyleName.ComponentIndex", "LogicalFontName.ComponentIndex" //$NON-NLS-1$ //$NON-NLS-2$
+    };
+
+    public static final String FONT_CHARACTER_ENCODING = "fontcharset.LogicalFontName.ComponentIndex"; //$NON-NLS-1$
+
+    public static final String EXCLUSION_RANGES = "exclusion.LogicalFontName.ComponentIndex"; //$NON-NLS-1$
+
+    public static final String FONT_FILE_NAME = "filename.PlatformFontName"; //$NON-NLS-1$
+
+    /**
+     * Available logical font families names.
+     */
+    public static final String[] LOGICAL_FONT_FAMILIES = {
+            "Serif", "SansSerif", "Monospaced", "Dialog", "DialogInput" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+    };
+
+    /**
+     * Available logical font names.
+     */
+    public static final String[] LOGICAL_FONT_NAMES = {
+            "serif", "serif.plain", "serif.bold", "serif.italic", "serif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "sansserif", "sansserif.plain", "sansserif.bold", "sansserif.italic", "sansserif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "monospaced", "monospaced.plain", "monospaced.bold", "monospaced.italic", "monospaced.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "dialog", "dialog.plain", "dialog.bold", "dialog.italic", "dialog.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "dialoginput", "dialoginput.plain", "dialoginput.bold", "dialoginput.italic", "dialoginput.bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+    };
+
+    /**
+     * Available logical font face names.
+     */
+    public static final String[] LOGICAL_FONT_FACES = {
+            "Serif", "Serif.plain", "Serif.bold", "Serif.italic", "Serif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "Sansserif", "Sansserif.plain", "Sansserif.bold", "Sansserif.italic", "Sansserif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "Monospaced", "Monospaced.plain", "Monospaced.bold", "Monospaced.italic", "Monospaced.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "Dialog", "Dialog.plain", "Dialog.bold", "Dialog.italic", "Dialog.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "Dialoginput", "Dialoginput.plain", "Dialoginput.bold", "Dialoginput.italic", "Dialoginput.bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+    };
+
+    /**
+     * Set of font style names.
+     * Font.getStyle() corresponds to indexes in STYLE_NAMES array.
+     */
+    public static final String[] STYLE_NAMES = {
+            "plain", "bold", "italic", "bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    };
+
+    /**
+     * Logical font styles names table where font styles names used 
+     * as the key and the value is the index of this style name.
+     */
+    private static final Hashtable<String, Integer> style_keys = new Hashtable<String, Integer>(4);
+
+    /**
+     * Initialize font styles keys table.
+     */
+    static {
+        for (int i = 0; i < STYLE_NAMES.length; i++){
+            style_keys.put(STYLE_NAMES[i], Integer.valueOf(i));
+        }
+    }
+
+    /**
+     * Return font style from the logical style name.
+     * 
+     * @param lName style name of the logical face
+     */
+    public static int getLogicalStyle(String lName){
+        Integer value = style_keys.get(lName);
+        return value != null ? value.intValue(): -1;
+    }
+
+    /**
+     * Set of possible "os" property values.
+     */
+    public static final String[] OS_VALUES = {
+            "NT", "98", "2000", "Me", "XP", // For Windows //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+            "Redhat", "Turbo", "SuSE"       // For Linux //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    };
+
+    /**
+     * Set of possible font.property file names.
+     * Language, Country, Encoding, OS, Version should be replaced with
+     * the values from current configuration.
+     */
+    public static final String[] FP_FILE_NAMES = {
+            "/lib/font.properties.Language_Country_Encoding.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country_Encoding.OS", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country_Encoding.Version", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country_Encoding", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country.OS", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country.Version", //$NON-NLS-1$
+            "/lib/font.properties.Language_Country", //$NON-NLS-1$
+            "/lib/font.properties.Language_Encoding.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.Language_Encoding.OS", //$NON-NLS-1$
+            "/lib/font.properties.Language_Encoding.Version", //$NON-NLS-1$
+            "/lib/font.properties.Language_Encoding", //$NON-NLS-1$
+            "/lib/font.properties.Language.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.Language.OS", //$NON-NLS-1$
+            "/lib/font.properties.Language.Version", //$NON-NLS-1$
+            "/lib/font.properties.Language", //$NON-NLS-1$
+            "/lib/font.properties.Encoding.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.Encoding.OS", //$NON-NLS-1$
+            "/lib/font.properties.Encoding.Version", //$NON-NLS-1$
+            "/lib/font.properties.Encoding", //$NON-NLS-1$
+            "/lib/font.properties.OSVersion", //$NON-NLS-1$
+            "/lib/font.properties.OS", //$NON-NLS-1$
+            "/lib/font.properties.Version", //$NON-NLS-1$
+            "/lib/font.properties" //$NON-NLS-1$
+    };
+
+    /**
+     * Table with all available font properties corresponding
+     * to the current system configuration.
+     */
+    public Hashtable<String, Vector<FontProperty>> fProperties = new Hashtable<String, Vector<FontProperty>>();
+    
+    public FontManager(){
+        allFamilies = getAllFamilies();
+        /*
+         * Creating and registering shutdown hook to free resources
+         * before object is destroyed.
+         */
+        //???AWT
+        //DisposeNativeHook shutdownHook = new DisposeNativeHook();
+        //Runtime.getRuntime().addShutdownHook(shutdownHook);
+    }
+
+    /**
+     * Maximum number of unreferenced font peers to keep.
+     */
+    public static final int EMPTY_FONTS_CAPACITY = 10;
+
+    /**
+     * Locale - Language ID hash table.
+     */
+    Hashtable<String, Short> tableLCID = new Hashtable<String, Short>();
+
+    /**
+     * Hash table that contains FontPeers instances.
+     */
+    public Hashtable<String, HashMapReference> fontsTable = new Hashtable<String, HashMapReference>();
+    
+    /**
+     * ReferenceQueue for HashMapReference objects to check
+     * if they were collected by garbage collector. 
+     */
+    public ReferenceQueue<FontPeer> queue = new ReferenceQueue<FontPeer>();
+
+    /**
+     * Singleton instance
+     */
+    public final static FontManager inst = CommonGraphics2DFactory.inst.getFontManager();
+
+    /**
+     * Gets singleton instance of FontManager
+     * 
+     * @return instance of FontManager implementation
+     */
+    public static FontManager getInstance() {
+        return inst;
+    }
+
+    /**
+     * Returns platform-dependent Font peer created from the specified 
+     * Font object from the table with cached FontPeers instances.
+     * 
+     * Note, this method checks whether FontPeer with specified parameters 
+     * exists in the table with cached FontPeers' instances. If there is no needed 
+     * instance - it is created and cached.
+     * 
+     * @param fontName name of the font 
+     * @param _fontStyle style of the font 
+     * @param size font size
+     * 
+     * @return platform dependent FontPeer implementation created from 
+     * the specified parameters
+     */
+    public FontPeer getFontPeer(String fontName, int _fontStyle, int size) {
+        updateFontsTable();
+        
+        FontPeer peer = null;
+        String key; 
+        String name;
+        int fontStyle = _fontStyle;
+        
+        int logicalIndex = getLogicalFaceIndex(fontName);
+        
+        if (logicalIndex != -1){
+            name = getLogicalFaceFromFont(fontStyle, logicalIndex);
+            fontStyle = getStyleFromLogicalFace(name);
+            key = name.concat(String.valueOf(size));
+        } else {
+            name = fontName;
+            key = name.concat(String.valueOf(fontStyle)).
+                    concat(String.valueOf(size));
+        }
+        
+        HashMapReference hmr   = fontsTable.get(key);
+        if (hmr != null) {
+            peer = hmr.get();
+        }
+
+        if (peer == null) {
+            peer = createFontPeer(name, fontStyle, size, logicalIndex);
+            if (peer == null){
+                peer = getFontPeer(DIALOG_NAME, fontStyle, size);
+            }
+            fontsTable.put(key, new HashMapReference(key, peer, queue));
+        }
+
+        return peer;
+    }
+    
+    /**
+     * Returns instance of font peer (logical or physical) according to the 
+     * specified parameters.
+     * 
+     * @param name font face name
+     * @param style style of the font
+     * @param size size of the font
+     * @param logicalIndex index of the logical face name in LOGICAL_FONT_FACES 
+     * array or -1 if desired font peer is not logical.
+     */
+    private FontPeer createFontPeer(String name, int style, int size, int logicalIndex){
+        FontPeer peer;
+        if (logicalIndex != -1){
+            peer = createLogicalFontPeer(name, style, size);
+        }else {
+            peer = createPhysicalFontPeer(name, style, size);
+        }
+        
+        return peer;
+    }
+    
+    /**
+     * Returns family name for logical face names as a parameter.
+     * 
+     * @param faceName logical font face name
+     */
+    public String getFamilyFromLogicalFace(String faceName){
+        int pos = faceName.indexOf("."); //$NON-NLS-1$
+        if (pos == -1){
+            return faceName;
+        }
+            
+        return faceName.substring(0, pos);
+    }
+            
+    /**
+     * Returns new logical font peer for the parameters specified using font 
+     * properties.
+     * 
+     * @param faceName face name of the logical font 
+     * @param style style of the font 
+     * @param size font size
+     * 
+     */
+    private FontPeer createLogicalFontPeer(String faceName, int style, int size){
+        String family = getFamilyFromLogicalFace(faceName);
+        FontProperty[] fps = getFontProperties(family.toLowerCase() + "." + style); //$NON-NLS-1$
+        if (fps != null){
+            int numFonts = fps.length;
+            FontPeerImpl[] physicalFonts = new FontPeerImpl[numFonts];
+            for (int i = 0; i < numFonts; i++){
+                FontProperty fp = fps[i];
+                
+                String name = fp.getName();
+                int fpStyle = fp.getStyle();
+                String key = name.concat(String.valueOf(fpStyle)).
+                    concat(String.valueOf(size));
+                
+                HashMapReference hmr   = fontsTable.get(key);
+                if (hmr != null) {
+                    physicalFonts[i] = (FontPeerImpl)hmr.get();
+                }
+
+                if (physicalFonts[i] == null){
+                    physicalFonts[i] = (FontPeerImpl)createPhysicalFontPeer(name, fpStyle, size);
+                    fontsTable.put(key, new HashMapReference(key, physicalFonts[i], queue));
+                }
+
+                if (physicalFonts[i] == null){
+                    physicalFonts[i] = (FontPeerImpl)getDefaultFont(style, size);
+                }
+            }
+            return new CompositeFont(family, faceName, style, size, fps, physicalFonts); 
+        }
+        
+        // if there is no property for this logical font - default font is to be
+        // created
+        FontPeerImpl peer = (FontPeerImpl)getDefaultFont(style, size);
+        
+        return peer;
+    }
+
+    /**
+     * Returns new physical font peer for the parameters specified using font properties
+     * This method must be overridden by subclasses implementations.
+     *  
+     * @param faceName face name or family name of the font 
+     * @param style style of the font 
+     * @param size font size
+     * 
+     */
+    public abstract FontPeer createPhysicalFontPeer(String name, int style, int size);
+    
+    /**
+     * Returns default font peer class with "Default" name that is usually 
+     * used when font with specified font names and style doesn't exsist 
+     * on a system. 
+     * 
+     * @param style style of the font
+     * @param size size of the font
+     */
+    public FontPeer getDefaultFont(int style, int size){
+        updateFontsTable();
+        
+        FontPeer peer = null;
+        String key = DEFAULT_NAME.concat(String.valueOf(style)).
+                    concat(String.valueOf(size));
+        
+        HashMapReference hmr   = fontsTable.get(key);
+        if (hmr != null) {
+            peer = hmr.get();
+        }
+
+        if (peer == null) {
+            peer = createDefaultFont(style, size);
+            
+            ((FontPeerImpl)peer).setFamily(DEFAULT_NAME);
+            ((FontPeerImpl)peer).setPSName(DEFAULT_NAME);
+            ((FontPeerImpl)peer).setFontName(DEFAULT_NAME);
+
+            fontsTable.put(key, new HashMapReference(key, peer, queue));
+        }
+
+        return peer;
+    }
+    
+    /**
+     * 
+     * Returns new default font peer with "Default" name for the parameters 
+     * specified. This method must be overridden by subclasses implementations.
+     *  
+     * @param style style of the font
+     * @param size size of the font
+     */
+    public abstract FontPeer createDefaultFont(int style, int size);
+    
+    /**
+     * Returns face name of the logical font, which is the result
+     * of specified font style and face style union.   
+     * 
+     * @param fontStyle specified style of the font
+     * @param logicalIndex index of the specified face from the 
+     * LOGICAL_FONT_FACES array
+     * @return resulting face name
+     */
+    public String getLogicalFaceFromFont(int fontStyle, int logicalIndex){
+        int style = 0;
+        String name = LOGICAL_FONT_FACES[logicalIndex];
+        int pos = name.indexOf("."); //$NON-NLS-1$
+        
+        if (pos == -1){
+            return createLogicalFace(name, fontStyle);
+        }
+        
+        String styleName = name.substring(pos+1);
+        name = name.substring(0, pos);
+        
+        // appending font style to the face style
+        style = fontStyle | getLogicalStyle(styleName);
+        
+        return createLogicalFace(name, style);
+    }
+    
+    /**
+     * Function returns style value from logical face name.
+     *  
+     * @param name face name
+     * @return font style
+     */
+    public int getStyleFromLogicalFace(String name){
+        int style;
+        int pos = name.indexOf("."); //$NON-NLS-1$
+        
+        if (pos == -1){
+            return Font.PLAIN;
+        }
+        
+        String styleName = name.substring(pos+1);
+        
+        style = getLogicalStyle(styleName);
+        
+        return style;
+    }
+
+    /**
+     * Returns logical face name corresponding to the logical
+     * family name and style of the font.
+     * 
+     * @param family font family
+     * @param styleIndex index of the style name from the STYLE_NAMES array 
+     */
+    public String createLogicalFace(String family, int styleIndex){
+        return family + "." + STYLE_NAMES[styleIndex]; //$NON-NLS-1$
+    }
+    
+    /**
+     * Return language Id from LCID hash corresponding to the specified locale
+     * 
+     * @param l specified locale
+     */
+    public Short getLCID(Locale l){
+        if (this.tableLCID.size() == 0){
+            initLCIDTable();
+        }
+
+        return tableLCID.get(l.toString());
+    }
+
+    /**
+     * Platform-dependent LCID table init.
+     */
+    public abstract void initLCIDTable();
+
+    /**
+     * Freeing native resources. This hook is used to avoid 
+     * sudden application exit and to free resources created in native code.
+     */
+    private class DisposeNativeHook extends Thread {
+
+        @Override
+        public void run() {
+            try{
+                /* Disposing native font peer's resources */
+                Enumeration<String> kEnum = fontsTable.keys();
+
+                while(kEnum.hasMoreElements()){
+                    Object key = kEnum.nextElement();
+                    HashMapReference hmr = fontsTable.remove(key);
+                    FontPeerImpl delPeer = (FontPeerImpl)hmr.get();
+                    
+                    if ((delPeer != null) && (delPeer.getClass() != CompositeFont.class)){
+                        // there's nothing to dispose in CompositeFont objects
+                        delPeer.dispose();
+                    }
+                }
+            } catch (Throwable t){
+                throw new RuntimeException(t);
+            }
+        }
+      }
+
+    /**
+     * Returns File object, created in a directory
+     * according to the System, where JVM is being ran.
+     *
+     * In Linux case we use ".fonts" directory (for fontconfig purpose),
+     * where font file from the stream will be stored, hence in LinuxFontManager this
+     * method is overridden.
+     * In Windows case we use Windows temp directory (default implementation)
+     *
+     */
+    public File getTempFontFile()throws IOException{
+        //???AWT
+        /*
+        File fontFile = File.createTempFile("jFont", ".ttf"); //$NON-NLS-1$ //$NON-NLS-2$
+        fontFile.deleteOnExit();
+
+        return fontFile;
+         */
+        if(NOT_IMP)
+            throw new NotImplementedException("getTempFontFile not Implemented");
+        return null;
+    }
+
+    /**
+     * Returns File object with font properties. It's name obtained using current 
+     * system configuration properties and locale settings. If no appropriate 
+     * file is found method returns null. 
+     */
+    public static File getFontPropertyFile(){
+        File file = null;
+
+        String javaHome = System.getProperty("java.home"); //$NON-NLS-1$
+        Locale l = Locale.getDefault();
+        String language = l.getLanguage();
+        String country = l.getCountry();
+        String fileEncoding = System.getProperty("file.encoding"); //$NON-NLS-1$
+
+        String os = System.getProperty("os.name"); //$NON-NLS-1$
+
+        int i = 0;
+
+        // OS names from system properties don't match
+        // OS identifiers used in font.property files
+        for (; i < OS_VALUES.length; i++){
+            if (os.endsWith(OS_VALUES[i])){
+                os = OS_VALUES[i];
+                break;
+            }
+        }
+
+        if (i == OS_VALUES.length){
+            os = null;
+        }
+
+        String version = System.getProperty("os.version"); //$NON-NLS-1$
+        String pathname;
+
+        for (i = 0; i < FP_FILE_NAMES.length; i++){
+            pathname = FP_FILE_NAMES[i];
+            if (os != null){
+                pathname = pathname.replaceFirst("OS", os); //$NON-NLS-1$
+            }
+
+            pathname = javaHome + pathname;
+
+            pathname = pathname.replaceAll("Language", language). //$NON-NLS-1$
+                                replaceAll("Country", country). //$NON-NLS-1$
+                                replaceAll("Encoding", fileEncoding). //$NON-NLS-1$
+                                replaceAll("Version", version); //$NON-NLS-1$
+
+            file = new File(pathname);
+
+            if (file.exists()){
+                break;
+            }
+        }
+
+        return file.exists() ? file : null;
+    }
+
+    /**
+     * Returns an array of integer range values
+     * if the parameter exclusionString has format:
+     *          Range
+     *          Range [, exclusionString]
+     *
+     *          Range:
+     *              Char-Char
+     *
+     *          Char:
+     *              HexDigit HexDigit HexDigit HexDigit
+     * 
+     * Method returns null if the specified string is null.
+     *  
+     * @param exclusionString string parameter in specified format
+     */
+    public static int[] parseIntervals(String exclusionString){
+        int[] results = null;
+
+        if (exclusionString == null){
+            return null;
+        }
+
+        String[] intervals = exclusionString.split(","); //$NON-NLS-1$
+
+        if (intervals != null){
+            int num = intervals.length;
+            if (num > 0){
+                results = new int[intervals.length << 1];
+                for (int i = 0; i < intervals.length; i++){
+                    String ranges[] = intervals[i].split("-"); //$NON-NLS-1$
+                    results[i*2] = Integer.parseInt(ranges[0], 16);
+                    results[i*2+1] = Integer.parseInt(ranges[1], 16);
+
+                }
+            }
+        }
+        return results;
+    }
+
+    /**
+     * Returns Properties from the properties file or null if 
+     * there is an error with FileInputStream processing.
+     * 
+     * @param file File object containing properties
+     */
+    public static Properties getProperties(File file){
+        Properties props = null;
+        FileInputStream fis = null;
+        try{
+            fis = new FileInputStream(file);
+            props = new Properties();
+            props.load(fis);
+        } catch (Exception e){
+            System.out.println(e);
+        }
+        return props;
+    }
+
+    /**
+     * Returns an array of FontProperties from the properties file
+     * with the specified property name "logical face.style". E.g. 
+     * "dialog.2" corresponds to the font family Dialog with bold style. 
+     *
+     * @param fpName key of the font properties in the properties set
+     */
+    public FontProperty[] getFontProperties(String fpName){
+        Vector<FontProperty> props = fProperties.get(fpName);
+        
+        if (props == null){
+            return null;
+        }
+
+        int size =  props.size();
+        
+        if (size == 0){
+            return null;
+        }
+
+        FontProperty[] fps = new FontProperty[size];
+        for (int i=0; i < fps.length; i++){
+            fps[i] = props.elementAt(i);
+        }
+        return fps;
+    }
+
+    /**
+     * Returns index of the font name in array of font names or -1 if 
+     * this font is not logical.
+     * 
+     * @param fontName specified font name
+     */
+    public static int getLogicalFaceIndex(String fontName){
+        for (int i=0; i<LOGICAL_FONT_NAMES.length; i++ ){
+            if (LOGICAL_FONT_NAMES[i].equalsIgnoreCase(fontName)){
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns true if specified family name is available in this 
+     * GraphicsEnvironment. 
+     * 
+     * @param familyName the specified font family name
+     */
+    public boolean isFamilyExist(String familyName){
+        return (getFamilyIndex(familyName) != -1);
+    }
+
+    /**
+     * Returns index of family name from the array of family names available in 
+     * this GraphicsEnvironment or -1 if no family name was found.
+     * 
+     * @param familyName specified font family name 
+     */
+    public int getFamilyIndex(String familyName){
+        for (int i=0; i<allFamilies.length; i++ ){
+            if (familyName.equalsIgnoreCase(allFamilies[i])){
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns family with index specified from the array of family names available in 
+     * this GraphicsEnvironment.
+     * 
+     * @param index index of the family in families names array 
+     */
+    public String getFamily(int index){
+        return allFamilies[index];
+    }
+    /**
+     * Returns index of face name from the array of face names available in 
+     * this GraphicsEnvironment or -1 if no face name was found. Default return 
+     * value is -1, method must be overridden by FontManager implementation.
+     * 
+     * @param faceName font face name which index is to be searched
+     */
+    public int getFaceIndex(String faceName){
+        return -1;
+    }
+
+    public abstract String[] getAllFamilies();
+
+    public abstract Font[] getAllFonts();
+    
+    /**
+     * Class contains SoftReference instance that can be stored in the 
+     * Hashtable by means of key field corresponding to it.
+     */
+    private class HashMapReference extends SoftReference<FontPeer> {
+        
+        /**
+         * The key for Hashtable.
+         */
+        private final String key;
+
+        /**
+         * Creates a new soft reference with the key specified and 
+         * adding this reference in the reference queue specified.
+         *
+         * @param key the key in Hashtable
+         * @param value object that corresponds to the key
+         * @param queue reference queue where reference is to be added 
+         */
+        public HashMapReference(final String key, final FontPeer value,
+                              final ReferenceQueue<FontPeer> queue) {
+            super(value, queue);
+            this.key = key;
+        }
+
+        /**
+         * Returns the key that corresponds to the SoftReference instance 
+         *
+         * @return the key in Hashtable with cached references
+         */
+        public Object getKey() {
+            return key;
+        }
+    }
+
+    /**
+     * Removes keys from the Hashtable with font peers which corresponding 
+     * HashMapReference objects were garbage collected.
+     */
+    private void updateFontsTable() {
+        HashMapReference r;
+        //???AWT
+        //while ((r = (HashMapReference)queue.poll()) != null) {
+        //    fontsTable.remove(r.getKey());
+        //}
+    }
+
+}
+
+
diff --git a/awt/org/apache/harmony/awt/gl/font/FontMetricsImpl.java b/awt/org/apache/harmony/awt/gl/font/FontMetricsImpl.java
new file mode 100644
index 0000000..7783317
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontMetricsImpl.java
@@ -0,0 +1,282 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import com.android.internal.awt.AndroidGraphics2D;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+//import java.awt.Paint;
+import java.awt.geom.AffineTransform;
+
+import android.graphics.Paint;
+
+/**
+ * FontMetrics implementation
+ */
+
+public class FontMetricsImpl extends FontMetrics {
+
+	private static final long serialVersionUID = 844695615201925138L;
+
+	// ascent of the font
+	private int ascent;
+
+	// descent of the font
+	private int descent;
+
+	// leading of the font
+	private int leading;
+
+	// maximum ascent of the font
+	private int maxAscent;
+
+	// maximum descent of the font
+	private int maxDescent;
+
+	// maximum advance of the font
+	private int maxAdvance;
+
+	// array of char advance widths
+	private int[] widths = new int[256];
+
+	// font peer corresponding to this FontPeerImpl
+	private transient FontPeerImpl peer;
+
+	// X scale parameter of the font transform
+	private float scaleX = 1;
+
+	public AndroidGraphics2D mSg;
+
+	private Font mFn;
+
+	// Y scale parameter of the font transform
+	private float scaleY = 1;
+
+	/**
+	 * Creates new FontMericsImpl object described by the specified Font.
+	 * 
+	 * @param fnt
+	 *            the specified Font object
+	 */
+	public FontMetricsImpl(Font fnt) {
+		super(fnt);
+		this.mFn = fnt;
+		
+		mSg = AndroidGraphics2D.getInstance();
+		Paint p = mSg.getAndroidPaint();
+		
+		this.ascent = (int)-p.ascent();
+		this.descent = (int)p.descent();
+		this.leading = p.getFontMetricsInt().leading;
+		
+		AffineTransform at = fnt.getTransform();
+		if (!at.isIdentity()) {
+			scaleX = (float) at.getScaleX();
+			scaleY = (float) at.getScaleY();
+		}
+				
+	    /*
+	     * metrics[5] - strikethrough thickness<p>
+	     * -metrics[6] - strikethrough offset<p>
+	     * metrics[7] - maximum char width<p>
+	     * metrics[8] - ascent in pixels<p>
+	     * metrics[9] - descent in pixles<p>
+	     * metrics[10] - external leading in pixels<p>
+	     * metrics[11] - underline thickness in pixels<p>
+	     * -metrics[12] - underline offset in pixels<p>
+	     * metrics[13] - strikethrough thickness in pixels<p>
+	     * -metrics[14] - strikethrough offset in pixels<p>
+	     * metrics[15] - maximum char width in pixels<p>
+
+	     * @param _baselineData an array of 3 elements with baseline offsets metrics<p>
+	     * _baselineData[0] - roman baseline offset<p> 
+	     * _baselineData[1] - center baseline offset<p>
+	     * _baselineData[2] - hanging baseline offset<p>
+	     */
+	}
+
+
+	/**
+	 * Initialize the array of the first 256 chars' advance widths of the Font
+	 * describing this FontMetricsImpl object.
+	 */
+	private void initWidths() {
+
+		this.widths = new int[256];
+		for (int chr = 0; chr < 256; chr++) {
+			widths[chr] = (int) (getFontPeer().charWidth((char) chr) * scaleX);
+		}
+
+	}
+
+	/**
+	 * Returns the ascent of the Font describing this FontMetricsImpl object.
+	 */
+	@Override
+	public int getAscent() {
+		return this.ascent;
+	}
+
+	/**
+	 * Returns the descent of the Font describing this FontMetricsImpl object.
+	 */
+	@Override
+	public int getDescent() {
+		return this.descent;
+	}
+
+	/**
+	 * Returns the leading of the Font describing this FontMetricsImpl object.
+	 */
+	@Override
+	public int getLeading() {
+		return this.leading;
+	}
+
+	/**
+	 * Returns the advance width of the specified char of the Font describing
+	 * this FontMetricsImpl object.
+	 * 
+	 * @param ch
+	 *            the char which width is to be returned
+	 * @return the advance width of the specified char of the Font describing
+	 *         this FontMetricsImpl object
+	 */
+	@Override
+	public int charWidth(int ch) {
+		if (ch < 256) {
+			return widths[ch];
+		}
+
+		return getFontPeer().charWidth((char) ch);
+	}
+
+	/**
+	 * Returns the advance width of the specified char of the Font describing
+	 * this FontMetricsImpl object.
+	 * 
+	 * @param ch
+	 *            the char which width is to be returned
+	 * @return the advance width of the specified char of the Font describing
+	 *         this FontMetricsImpl object
+	 */
+	@Override
+	public int charWidth(char ch) {
+		if (ch < 256) {
+			return widths[ch];
+		}
+		return (int) (getFontPeer().charWidth(ch) * scaleX);
+	}
+
+	/**
+	 * Returns the maximum advance of the Font describing this FontMetricsImpl
+	 * object.
+	 */
+	@Override
+	public int getMaxAdvance() {
+		return this.maxAdvance;
+	}
+
+	/**
+	 * Returns the maximum ascent of the Font describing this FontMetricsImpl
+	 * object.
+	 */
+	@Override
+	public int getMaxAscent() {
+		return this.maxAscent;
+	}
+
+	/**
+	 * Returns the maximum descent of the Font describing this FontMetricsImpl
+	 * object.
+	 */
+	@SuppressWarnings("deprecation")
+	@Deprecated
+	@Override
+	public int getMaxDecent() {
+		return this.maxDescent;
+	}
+
+	/**
+	 * Returns the maximum descent of the Font describing this FontMetricsImpl
+	 * object.
+	 */
+	@Override
+	public int getMaxDescent() {
+		return this.maxDescent;
+	}
+
+	/**
+	 * Returns the advance widths of the first 256 characters in the Font
+	 * describing this FontMetricsImpl object.
+	 */
+	@Override
+	public int[] getWidths() {
+		return this.widths;
+	}
+
+	/**
+	 * Returns the total advance width of the specified string in the metrics of
+	 * the Font describing this FontMetricsImpl object.
+	 * 
+	 * @param str
+	 *            the String which width is to be measured
+	 * @return the total advance width of the specified string in the metrics of
+	 *         the Font describing this FontMetricsImpl object
+	 */
+	@Override
+	public int stringWidth(String str) {
+
+		int width = 0;
+		char chr;
+
+		for (int i = 0; i < str.length(); i++) {
+			chr = str.charAt(i);
+			width += charWidth(chr);
+		}
+		return width;
+
+		/*
+		 * float res = 0; int ln = str.length(); char[] c = new char[ln]; float[] f =
+		 * new float[ln]; str.getChars(0, ln, c, 0); mSg.getPaint().getTextWidths(c, 0,
+		 * ln, f);
+		 * 
+		 * for(int i = 0; i < f.length; i++) { res += f[i]; } return (int)res;
+		 */
+	}
+
+	/**
+	 * Returns FontPeer implementation of the Font describing this
+	 * FontMetricsImpl object.
+	 * 
+	 * @return a FontPeer object, that is the platform dependent FontPeer
+	 *         implementation for the Font describing this FontMetricsImpl
+	 *         object.
+	 */
+	@SuppressWarnings("deprecation")
+	public FontPeerImpl getFontPeer() {
+		if (peer == null) {
+			peer = (FontPeerImpl) font.getPeer();
+		}
+		return peer;
+	}
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontPeerImpl.java b/awt/org/apache/harmony/awt/gl/font/FontPeerImpl.java
new file mode 100644
index 0000000..14ff997
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontPeerImpl.java
@@ -0,0 +1,499 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+
+import com.android.internal.awt.AndroidGraphics2D;
+import com.android.internal.awt.AndroidGraphicsFactory;
+
+import java.awt.Graphics2D;
+import java.awt.Toolkit;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.peer.FontPeer;
+
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+import android.graphics.Paint;
+
+/**
+ * Abstract class for platform dependent peer implementation of the Font class.
+ */
+public abstract class FontPeerImpl implements FontPeer{
+
+    // ascent of this font peer (in pixels)
+    int ascent;
+
+    // descent of this font peer (in pixels)
+    int descent;
+
+    // leading of this font peer (in pixels) 
+    int leading;
+
+    // logical maximum advance of this font peer (in pixels)
+    int maxAdvance;
+
+    // the height of this font peer
+    float height;
+
+    // the style of this font peer
+    int style;
+
+    // the point size of this font peer (in pixels)
+    int size;
+
+    // the logical hight of this font peer (in pixels)
+    int logicalHeight;
+
+    // the name of this font peer
+    String name;
+
+    // family name of this font peer
+    String fontFamilyName;
+
+    // the Face name of this font peer
+    String faceName;
+
+    // bounds rectanlge of the largest character in this font peer
+    Rectangle2D maxCharBounds;
+
+    // italic angle value of this font peer
+    float italicAngle = 0.0f;
+
+    // the number of glyphs supported by this font peer
+    int numGlyphs = 0;
+
+    // native font handle
+    long pFont;
+
+    // cached line metrics object
+    LineMetricsImpl nlm;
+
+    // the postscript name of this font peer
+    String psName = null;
+
+    /**
+     * Default glyph index, that is used, when the desired glyph
+     * is unsupported in this Font.
+     */
+    public char defaultChar = (char)0xFFFF;
+
+    /**
+     * Uniform LineMetrics flag, that is false for CompositeFont.  
+     * Default value is true.
+     */
+    boolean uniformLM = true;
+
+    /**
+     * Flag of the type of this Font that is indicate is the Font
+     * has TrueType or Type1 type. Default value is FONT_TYPE_UNDEF. 
+     */
+    int fontType = FontManager.FONT_TYPE_UNDEF;
+
+    /**
+     * Flag if this Font was created from stream, 
+     * this parameter used in finilize method.
+     */ 
+    private boolean createdFromStream = false;  
+    
+    // temorary Font file name, if this FontPeerImpl was created from InputStream 
+    private String tempFontFileName = null;     
+    
+    // cached FontExtraMetrics object related to this font peer
+    FontExtraMetrics extraMetrix = null;
+
+    public abstract FontExtraMetrics getExtraMetrics();
+    
+    /**
+     * Returns LineMetrics object with specified parameters
+     * @param str specified String
+     * @param frc specified render context
+     * @param at specified affine transform
+     * @return
+     */
+    public abstract LineMetrics getLineMetrics(String str, FontRenderContext frc, AffineTransform at);
+
+    /**
+     * Returns postscript name of the font.  
+     */
+    public abstract String getPSName();
+    
+	//private Graphics2D g = ((AndroidGraphicsFactory)Toolkit.getDefaultToolkit().getGraphicsFactory()).getGraphics2D();
+    //private Graphics2D g = AndroidGraphics2D.getInstance();
+
+    /**
+     * Set postscript name of the font to the specified parameter.  
+     */
+    public void setPSName(String name){
+        this.psName = name;
+    }
+    
+    /**
+     * Returns code of the missing glyph. 
+     */
+    public abstract int getMissingGlyphCode();
+
+    /**
+     * Returns Glyph representation of the given char.
+     * @param ch specified char
+     */
+    public abstract Glyph getGlyph(char ch);
+
+    /**
+     * Disposes nesessary resources.
+     */
+    public abstract void dispose();
+
+    /**
+     * Returns Glyph represeting missing char. 
+     */
+    public abstract Glyph getDefaultGlyph();
+
+    /**
+     * Returns true if this FontPeerImpl can display the specified char
+     */
+    public abstract boolean canDisplay(char c);
+
+    /**
+     * Returns family name of the font in specified locale settings.
+     * @param l specified Locale
+     */
+    public String getFamily(Locale l){
+        return this.getFamily();
+    }
+
+    /**
+     * Sets family name of the font in specified locale settings.
+     */
+    public void setFamily(String familyName){
+        this.fontFamilyName = familyName;
+    }
+
+    /**
+     * Returns face name of the font in specified locale settings.
+     * @param l specified Locale
+     */
+    public String getFontName(Locale l){
+        return this.getFontName();
+    }
+
+    /**
+     * Sets font name of the font in specified locale settings.
+     */
+    public void setFontName(String fontName){
+        this.faceName = fontName;
+    }
+
+    /**
+     * Returns true, if this font peer was created from InputStream, false otherwise.
+     * In case of creating fonts from InputStream some font peer implementations 
+     * may need to free temporary resources.
+     */
+    public boolean isCreatedFromStream(){
+        return this.createdFromStream;
+    }
+
+    /**
+     * Sets createdFromStream flag to the specified parameter.
+     * If parameter is true it means font peer was created from InputStream.
+     * 
+     * @param value true, if font peer was created from InputStream 
+     */
+    public void setCreatedFromStream(boolean value){
+        this.createdFromStream = value;
+    }
+
+    /**
+     * Returns font file name of this font.
+     */
+    public String getTempFontFileName(){
+        return this.tempFontFileName;
+    }
+
+    /**
+     * Sets font file name of this font to the specified one.
+     * @param value String representing font file name
+     */
+    public void setFontFileName(String value){
+        this.tempFontFileName = value;
+    }
+
+    /**
+     * Returns the advance width of the specified char of this FontPeerImpl.
+     * Note, if glyph is absent in the font's glyphset - returned value 
+     * is the advance of the deafualt glyph. For escape-chars returned 
+     * width value is 0.
+     * 
+     * @param ch the char which width is to be returned
+     * @return the advance width of the specified char of this FontPeerImpl
+     */
+    public int charWidth(char ch) {
+    	Paint p;
+    	AndroidGraphics2D g = AndroidGraphics2D.getInstance();
+    	if(g == null) {
+    		throw new RuntimeException("AndroidGraphics2D not instantiated!");
+    	}
+   		p = ((AndroidGraphics2D)g).getAndroidPaint();
+   		char[] ca = {ch};
+   		float[] fa = new float[1];
+   		p.getTextWidths(ca, 0, 1, fa);
+   		return (int)fa[0];
+    }
+
+    /**
+     * Returns the advance width of the specified char of this FontPeerImpl.
+     * 
+     * @param ind the char which width is to be returned
+     * @return the advance width of the specified char of this FontPeerImpl
+     */
+    public int charWidth(int ind) {
+        return charWidth((char)ind);
+    }
+
+    /**
+     * Returns an array of Glyphs that represent characters from the specified 
+     * Unicode range.
+     * 
+     * @param uFirst start position in Unicode range
+     * @param uLast end position in Unicode range
+     * @return
+     */
+    public Glyph[] getGlyphs(char uFirst, char uLast) {
+
+        char i = uFirst;
+        int len = uLast - uFirst;
+        ArrayList<Glyph> lst = new ArrayList<Glyph>(len);
+
+        if (size < 0) {
+            // awt.09=min range bound value is greater than max range bound
+            throw new IllegalArgumentException(Messages.getString("awt.09")); //$NON-NLS-1$
+        }
+
+        while (i < uLast) {
+            lst.add(this.getGlyph(i));
+        }
+
+        return (Glyph[]) lst.toArray();
+    }
+
+    /**
+     * Returns an array of Glyphs representing given array of chars.
+     * 
+     * @param chars specified array of chars
+     */
+    public Glyph[] getGlyphs(char[] chars) {
+        if (chars == null){
+            return null;
+        }
+
+        Glyph[] result = new Glyph[chars.length];
+
+        for (int i = 0; i < chars.length; i++) {
+            result[i] = this.getGlyph(chars[i]);
+        }
+        return result;
+    }
+
+    /**
+     * Returns an array of Glyphs representing given string.
+     * 
+     * @param str specified string
+     */
+    public Glyph[] getGlyphs(String str) {
+        char[] chars = str.toCharArray();
+        return this.getGlyphs(chars);
+    }
+
+    /**
+     * Returns family name of this FontPeerImpl.
+     */
+    public String getFamily() {
+        return fontFamilyName;
+    }
+
+    /**
+     * Returns face name of this FontPeerImpl.
+     */
+    public String getFontName() {
+        if (this.fontType == FontManager.FONT_TYPE_T1){
+            return this.fontFamilyName;
+        }
+
+        return faceName;
+    }
+
+    /**
+     * Returns height of this font peer in pixels. 
+     */
+    public int getLogicalHeight() {
+        return logicalHeight;
+    }
+
+    /**
+     * Sets height of this font peer in pixels to the given value.
+     * 
+     * @param newHeight new height in pixels value
+     */
+    public void setLogicalHeight(int newHeight) {
+        logicalHeight = newHeight;
+    }
+
+    /**
+     * Returns font size. 
+     */
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * Returns font style. 
+     */
+    public int getStyle() {
+        return style;
+    }
+
+    /**
+     * Returns font name. 
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the bounds of the largest char in this FontPeerImpl in 
+     * specified render context.
+     * 
+     * @param frc specified FontRenderContext
+     */
+    public Rectangle2D getMaxCharBounds(FontRenderContext frc) {
+        return maxCharBounds;
+    }
+
+    /**
+     * Returns the number of glyphs in this FontPeerImpl.
+     */
+    public int getNumGlyphs() {
+        return  numGlyphs;
+    }
+
+    /**
+     * Returns tangens of the italic angle of this FontPeerImpl.
+     * If the FontPeerImpl has TrueType font type, italic angle value can be 
+     * calculated as (CharSlopeRun / CharSlopeRise) in terms of GDI.
+     */
+    public float getItalicAngle() {
+        return italicAngle;
+    }
+
+    /**
+     * Returns height of this font peer. 
+     */
+    public float getHeight(){
+        return height;
+    }
+
+    /**
+     * Returns cached LineMetrics object of this font peer. 
+     */
+    public LineMetrics getLineMetrics(){
+        return nlm;
+    }
+
+    /**
+     * Returns native font handle of this font peer. 
+     */
+    public long getFontHandle(){
+        return pFont;
+    }
+
+    /**
+     * Returns ascent of this font peer. 
+     */
+    public int getAscent(){
+    	Paint p;
+    	AndroidGraphics2D g = AndroidGraphics2D.getInstance();
+    	if(g == null) {
+    		throw new RuntimeException("AndroidGraphics2D not instantiated!");
+    	}
+   		p = ((AndroidGraphics2D)g).getAndroidPaint();
+   		return (int)p.ascent();
+        //return ascent;
+    }
+
+    /**
+     * Returns descent of this font peer. 
+     */
+    public int getDescent(){
+        return descent;
+    }
+
+    /**
+     * Returns leading of this font peer. 
+     */
+    public int getLeading(){
+        return leading;
+    }
+
+    /**
+     * Returns true if this font peer has uniform line metrics. 
+     */
+    public boolean hasUniformLineMetrics(){
+        return uniformLM;
+    }
+
+    /**
+     * Returns type of this font.
+     *  
+     * @return one of constant font type values. 
+     */    
+    public int getFontType(){
+        return fontType;
+    }
+
+    /**
+     * Sets new font type to the font object.
+     * 
+     * @param newType new type value
+     */
+    public void setFontType(int newType){
+        if (newType == FontManager.FONT_TYPE_T1 || newType == FontManager.FONT_TYPE_TT){
+            fontType = newType;
+        }
+    }
+
+    /**
+     * Sets new font type to the font object.
+     * 
+     * @param newType new type value
+     */
+    @Override
+    protected void finalize() throws Throwable {
+      super.finalize();
+      
+      dispose();
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/FontProperty.java b/awt/org/apache/harmony/awt/gl/font/FontProperty.java
new file mode 100644
index 0000000..4eb7cbb
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/FontProperty.java
@@ -0,0 +1,106 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+
+/**
+ * Class containing font property information. This information can be found 
+ * in font.property files. See API documentation, logical fonts description part. 
+ *
+ */
+public class FontProperty {
+
+    // font file name 
+    String fileName = null;
+    
+    // name of the encoding to be used 
+    String encoding = null;
+    
+    // array of exclusion ranges (pairs of low and high unicode exclusion bounds)
+    int[] exclRange = null;
+    
+    // font face name
+    String name = null;
+    
+    // font style
+    int style = -1;
+
+    /**
+     * Returns font style of this font property. 
+     */
+    public int getStyle(){
+        return this.style;
+    }
+
+    /**
+     * Returns font name of this font property. 
+     */
+    public String getName(){
+        return this.name;
+    }
+
+    /**
+     * Returns encoding used in this font property. 
+     */
+    public String getEncoding(){
+        return this.encoding;
+    }
+    
+    /**
+     * Returns an array of exclusion ranges. This array contain pairs of 
+     * low and high bounds of the intervals of characters to ignore in 
+     * total Unicode characters range.   
+     */
+    public int[] getExclusionRange(){
+        return this.exclRange;
+    }
+
+    /**
+     * Returns file name of the font that is described by this font property. 
+     */
+    public String getFileName(){
+        return this.fileName;
+    }
+
+    /**
+     * Returns true if specified character covered by exclusion ranges of this 
+     * font property, false otherwise.
+     * 
+     * @param ch specified char to check
+     */
+    public boolean isCharExcluded(char ch){
+        if (exclRange == null ){
+            return false;
+        }
+
+        for (int i = 0; i < exclRange.length;){
+            int lb = exclRange[i++];
+            int hb = exclRange[i++];
+
+            if (ch >= lb && ch <= hb){
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/Glyph.java b/awt/org/apache/harmony/awt/gl/font/Glyph.java
new file mode 100644
index 0000000..44b8809
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/Glyph.java
@@ -0,0 +1,236 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Shape;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+import java.awt.image.BufferedImage;
+
+public abstract class Glyph{
+
+    // character of the glyph
+    char glChar;
+    
+    // precise glyph metrics
+    GlyphMetrics glMetrics;
+    
+    // glyph metrics in pixels
+    GlyphMetrics glPointMetrics;
+    
+    //  glyph code of this Glyph
+    int glCode;
+    
+    // justification info of this glyph
+    GlyphJustificationInfo glJustInfo;
+    
+    // native font handle of the font corresponding to this glyph
+    long pFont;
+    
+    // size of the font corresponding to this glyph
+    int fontSize;
+    
+    // bitmap representation of the glyph
+    byte[] bitmap = null;
+    
+    // Buffered image representation of the glyph
+    BufferedImage image;
+    
+    // shape that representing the outline of this glyph
+    Shape glOutline = null;
+
+    /**
+     * image bitmap parameters
+     */
+    
+    //  top side bearing
+    public int bmp_top = 0;
+    
+    // left side bearing
+    public int bmp_left = 0;
+
+    // number of bytes in row
+    public int bmp_pitch;
+    
+    // number of rows
+    public int bmp_rows;
+    
+    // width of the row
+    public int bmp_width;
+
+    /**
+     *  Retruns handle to Native Font object
+     */
+    public long getPFont(){
+        return this.pFont;
+    }
+
+    /**
+     *  Retruns char value of this glyph object
+     */
+    public char getChar(){
+        return glChar;
+    }
+
+    /**
+     *  Retruns precise width of this glyph object
+     */
+    public int getWidth(){
+        return Math.round((float)glMetrics.getBounds2D().getWidth());
+    }
+
+    /**
+     *  Retruns precise height of this glyph object
+     */
+    public int getHeight(){
+        return Math.round((float)glMetrics.getBounds2D().getHeight());
+    }
+
+    /**
+     *  Retruns glyph code of this glyph object
+     */
+    public int getGlyphCode(){
+        return glCode;
+    }
+
+    /**
+     *  Retruns GlyphMetrics of this glyph object with precise metrics.
+     */
+    public GlyphMetrics getGlyphMetrics(){
+        return glMetrics;
+    }
+
+    /**
+     *  Retruns GlyphMetrics of this glyph object in pixels.
+     */
+    public GlyphMetrics getGlyphPointMetrics(){
+        return glPointMetrics;
+    }
+
+    /**
+     *  Retruns GlyphJustificationInfo of this glyph object
+     */
+    public GlyphJustificationInfo getGlyphJustificationInfo(){
+        return glJustInfo;
+    }
+
+    /**
+     *  Sets JustificationInfo of this glyph object
+     * 
+     * @param newJustInfo GlyphJustificationInfo object to set to the Glyph object 
+     */
+    public void setGlyphJustificationInfo(GlyphJustificationInfo newJustInfo){
+        this.glJustInfo = newJustInfo;
+    }
+
+    /**
+     * Returns an int array of 3 elements, so-called ABC structure that contains 
+     * the width of the character:
+     * 1st element = left side bearing of the glyph
+     * 2nd element = width of the glyph
+     * 3d element = right side bearing of the glyph 
+     */
+    public int[] getABC(){
+        int[] abc = new int[3];
+        abc[0] = (int)glMetrics.getLSB();
+        abc[1] = (int)glMetrics.getBounds2D().getWidth();
+        abc[2] = (int)glMetrics.getRSB();
+
+        return abc;
+    }
+
+    /**
+     * Sets BufferedImage representation of this glyph to the specified parameter.
+     * 
+     * @param newImage new BufferedImage object to be set as BufferedImage 
+     * representation.
+     */
+    public void setImage(BufferedImage newImage){
+        this.image = newImage;
+    }
+
+    /**
+     * Returns true if this Glyph and specified object are equal.
+     */
+    @Override
+    public boolean equals(Object obj){
+         if (obj == this) {
+            return true;
+        }
+
+        if (obj != null) {
+          try {
+            Glyph gl = (Glyph)obj;
+
+            return  ((this.getChar() == gl.getChar())
+              && (this.getGlyphMetrics().equals(gl.getGlyphMetrics()))
+              && (this.getGlyphCode() == gl.getGlyphCode()));
+          } catch (ClassCastException e) {
+          }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns height of the glyph in points. 
+     */
+    public int getPointHeight(){
+        return (int)glPointMetrics.getBounds2D().getHeight();
+    }
+
+    /**
+     * Returns width of the glyph in points. 
+     */
+    public int getPointWidth(){
+        return (int)glPointMetrics.getBounds2D().getWidth();
+    }
+
+    public Shape getShape(){
+        if (glOutline == null){
+            glOutline = initOutline(this.glChar);
+        }
+        return glOutline;
+    }
+
+    /**
+     * Sets BufferedImage representation of this glyph.
+     */
+    public BufferedImage getImage(){
+        //!! Implementation classes must override this method
+        return null;
+    }
+
+    /**
+     *  Returns array of bytes, representing image of this glyph
+     */
+    public abstract byte[] getBitmap();
+
+    /**
+     * Returns shape that represents outline of the specified character. 
+     * 
+     * @param c specified character
+     */
+    public abstract Shape initOutline(char c);
+
+}
+
+
diff --git a/awt/org/apache/harmony/awt/gl/font/LineMetricsImpl.java b/awt/org/apache/harmony/awt/gl/font/LineMetricsImpl.java
new file mode 100644
index 0000000..370146d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/LineMetricsImpl.java
@@ -0,0 +1,412 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.LineMetrics;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ *
+ * LineMetrics implementation class.
+ */
+
+public class LineMetricsImpl extends LineMetrics implements Cloneable{
+
+    // array of baseline offsets
+    float[] baselineOffsets;
+
+    // the number of characters to measure
+    int numChars;
+
+    // baseline index of the font corresponding to this line metrics
+    int baseLineIndex;
+
+    // underline thickness
+    float underlineThickness;
+
+    // underline offset
+    float underlineOffset;
+
+    // strikethrough thickness
+    float strikethroughThickness;
+
+    // strikethrough offset
+    float strikethroughOffset;
+
+    // External leading
+    float leading;
+
+    // Height of the font ( == (ascent+descent+leading))
+    float height;
+
+    // Ascent of the font
+    float ascent;
+
+    // Descent of the font
+    float descent;
+
+    // Width of the widest char in the font
+    float maxCharWidth;
+
+    // underline thickness (in pixels)
+    int lUnderlineThickness;
+
+    // underline offset (in pixels)
+    int lUnderlineOffset;
+
+    // strikethrough thickness (in pixels)
+    int lStrikethroughThickness;
+
+    // strikethrough offset (in pixels)
+    int lStrikethroughOffset;
+
+    // External leading (in pixels)
+    int lLeading;
+
+    // Height of the font ( == (ascent+descent+leading)) (in pixels)
+    int lHeight;
+
+    // Ascent of the font (in pixels)
+    int lAscent;
+    
+    // Descent of the font (in pixels)
+    int lDescent;
+
+    //  Width of the widest char in the font (in pixels)
+    int lMaxCharWidth;
+
+    // units per EM square in font value
+    int units_per_EM = 0;
+
+    /**
+     * Creates LineMetricsImpl object from specified parameters. If baseline data parameter
+     * is null than {0, (-ascent+descent)/2, -ascent} values are used for baseline offsets.
+     *  
+     * @param len a number of characters 
+     * @param metrics an array of 16 elements with metrics values that can be 
+     * initialized in native code.<p>
+     * metrics[0] - ascent<p>
+     * metrics[1] - descent<p>
+     * metrics[2] - external leading<p>
+     * metrics[3] - underline thickness<p>
+     * -metrics[4] - underline offset<p>
+     * metrics[5] - strikethrough thickness<p>
+     * -metrics[6] - strikethrough offset<p>
+     * metrics[7] - maximum char width<p>
+     * metrics[8] - ascent in pixels<p>
+     * metrics[9] - descent in pixles<p>
+     * metrics[10] - external leading in pixels<p>
+     * metrics[11] - underline thickness in pixels<p>
+     * -metrics[12] - underline offset in pixels<p>
+     * metrics[13] - strikethrough thickness in pixels<p>
+     * -metrics[14] - strikethrough offset in pixels<p>
+     * metrics[15] - maximum char width in pixels<p>
+
+     * @param _baselineData an array of 3 elements with baseline offsets metrics<p>
+     * _baselineData[0] - roman baseline offset<p> 
+     * _baselineData[1] - center baseline offset<p>
+     * _baselineData[2] - hanging baseline offset<p>
+     */
+    public LineMetricsImpl(int len, float[] metrics, float[] _baselineData){
+        numChars = len;
+
+        ascent = metrics[0];    // Ascent of the font
+        descent = metrics[1];   // Descent of the font
+        leading = metrics[2];  // External leading
+        height = metrics[0] + metrics[1] + metrics[2];  // Height of the font ( == (ascent + descent + leading))
+    }
+
+    /**
+     * Creates LineMetricsImpl object from specified parameters. If baseline data parameter
+     * is null than {0, (-ascent+descent)/2, -ascent} values are used for baseline offsets.
+     *  
+     * @param _numChars number of chars 
+     * @param _baseLineIndex index of the baseline offset
+     * @param _baselineOffsets an array of baseline offsets
+     * @param _underlineThickness underline thickness
+     * @param _underlineOffset underline offset
+     * @param _strikethroughThickness strikethrough thickness
+     * @param _strikethroughOffset strinkethrough offset
+     * @param _leading leading of the font
+     * @param _height font height
+     * @param _ascent ascent of the font
+     * @param _descent descent of the font
+     * @param _maxCharWidth max char width
+     */
+    public LineMetricsImpl(int _numChars, int _baseLineIndex,
+            float[] _baselineOffsets, float _underlineThickness,
+            float _underlineOffset, float _strikethroughThickness,
+            float _strikethroughOffset, float _leading, float _height,
+            float _ascent, float _descent, float _maxCharWidth) {
+
+        numChars = _numChars;
+        baseLineIndex = _baseLineIndex;
+        underlineThickness = _underlineThickness;
+        underlineOffset = _underlineOffset;
+        strikethroughThickness = _strikethroughThickness;
+        strikethroughOffset = _strikethroughOffset;
+        leading = _leading;
+        height = _height;
+        ascent = _ascent;
+        descent = _descent;
+        baselineOffsets = _baselineOffsets;
+        lUnderlineThickness = (int) underlineThickness;
+        lUnderlineOffset = (int) underlineOffset;
+        lStrikethroughThickness = (int) strikethroughThickness;
+        lStrikethroughOffset = (int) strikethroughOffset;
+        lLeading = (int) leading;
+        lHeight = (int) height;
+        lAscent = (int) ascent;
+        lDescent = (int) descent;
+        maxCharWidth = _maxCharWidth;
+    }
+
+    public LineMetricsImpl(){
+
+    }
+
+    /**
+     * All metrics are scaled according to scaleX and scaleY values. 
+     * This function helps to recompute metrics according to the scale factors
+     * of desired AffineTransform.
+     * 
+     * @param scaleX scale X factor
+     * @param scaleY scale Y factor
+     */
+    public void scale(float scaleX, float scaleY){
+        float absScaleX = Math.abs(scaleX);
+        float absScaleY = Math.abs(scaleY);
+
+        underlineThickness *= absScaleY;
+        underlineOffset *= scaleY;
+        strikethroughThickness *= absScaleY;
+        strikethroughOffset *= scaleY;
+        leading *= absScaleY;
+        height *= absScaleY;
+        ascent *= absScaleY;
+        descent *= absScaleY;
+
+        if(baselineOffsets == null) {
+            getBaselineOffsets();
+        }
+
+        for (int i=0; i< baselineOffsets.length; i++){
+            baselineOffsets[i] *= scaleY;
+        }
+
+        lUnderlineThickness *= absScaleY;
+        lUnderlineOffset *= scaleY;
+        lStrikethroughThickness *= absScaleY;
+        lStrikethroughOffset *= scaleY;
+        lLeading  *= absScaleY;
+        lHeight *= absScaleY;
+        lAscent *= absScaleY;
+        lDescent *= absScaleY;
+        maxCharWidth *= absScaleX;
+
+    }
+
+
+    /**
+     * Returns offset of the baseline.
+     */
+    @Override
+    public float[] getBaselineOffsets() {
+        // XXX: at the moment there only horizontal metrics are taken into
+        // account. If there is no baseline information in TrueType font
+        // file default values used: {0, -ascent, (-ascent+descent)/2}
+
+        return baselineOffsets;
+    }
+
+    /**
+     * Returns a number of chars in specified text
+     */
+    @Override
+    public int getNumChars() {
+        return numChars;
+    }
+
+    /**
+     * Returns index of the baseline, one of predefined constants.
+     */
+    @Override
+    public int getBaselineIndex() {
+        // Baseline index is the deafult baseline index value
+        // taken from the TrueType table "BASE".
+        return baseLineIndex;
+    }
+
+    /**
+     * Returns thickness of the Underline.
+     */
+    @Override
+    public float getUnderlineThickness() {
+        return underlineThickness;
+    }
+
+    /**
+     * Returns offset of the Underline.
+     */
+    @Override
+    public float getUnderlineOffset() {
+        return underlineOffset;
+    }
+
+    /**
+     * Returns thickness of the Strikethrough line.
+     */
+    @Override
+    public float getStrikethroughThickness() {
+        return strikethroughThickness;
+    }
+
+    /**
+     * Returns offset of the Strikethrough line.
+     */
+    @Override
+    public float getStrikethroughOffset() {
+        return strikethroughOffset;
+    }
+
+    /**
+     * Returns the leading.
+     */
+    @Override
+    public float getLeading() {
+        return leading;
+    }
+
+    /**
+     * Returns the height of the font.
+     */
+    @Override
+    public float getHeight() {
+        //return height; // equals to (ascent + descent + leading);
+    	return ascent + descent + leading;
+    }
+
+    /**
+     * Returns the descent.
+     */
+    @Override
+    public float getDescent() {
+        return descent;
+    }
+
+    /**
+     * Returns the ascent.
+     */
+    @Override
+    public float getAscent() {
+        return ascent;
+    }
+
+    /**
+     * Returns logical thickness of the Underline.
+     */
+    public int getLogicalUnderlineThickness() {
+        return lUnderlineThickness;
+    }
+
+    /**
+     * Returns logical offset of the Underline.
+     */
+    public int getLogicalUnderlineOffset() {
+        return lUnderlineOffset;
+    }
+
+    /**
+     * Returns logical thickness of the Strikethrough line.
+     */
+    public int getLogicalStrikethroughThickness() {
+        return lStrikethroughThickness;
+    }
+
+    /**
+     * Returns logical offset of the Strikethrough line.
+     */
+    public int getLogicalStrikethroughOffset() {
+        return lStrikethroughOffset;
+    }
+
+    /**
+     * Returns the logical leading.
+     */
+    public int getLogicalLeading() {
+        return lLeading;
+    }
+
+    /**
+     * Returns the logical height of the font.
+     */
+    public int getLogicalHeight() {
+        return lHeight; // equals to (ascent + descent + leading);
+    }
+
+    /**
+     * Returns the logical descent.
+     */
+    public int getLogicalDescent() {
+        return lDescent;
+    }
+
+    /**
+     * Returns the logical ascent.
+     */
+    public int getLogicalAscent() {
+        return lAscent;
+    }
+
+    /**
+     * Returns the logical size of the widest char.
+     */
+    public int getLogicalMaxCharWidth() {
+        return lMaxCharWidth;
+    }
+
+    /**
+     * Returns the size of the widest char.
+     */
+    public float getMaxCharWidth() {
+        return maxCharWidth;
+    }
+
+    /**
+     * Set num chars to the desired value.
+     * 
+     * @param num specified number of chars
+     */
+    public void setNumChars(int num){
+        numChars = num;
+    }
+
+    @Override
+    public Object clone(){
+        try{
+            return super.clone();
+        }catch (CloneNotSupportedException e){
+            return null;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/font/TextDecorator.java b/awt/org/apache/harmony/awt/gl/font/TextDecorator.java
new file mode 100644
index 0000000..81905fd
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/TextDecorator.java
@@ -0,0 +1,433 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.font.TextAttribute;
+import java.awt.geom.Area;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.Map;
+
+/**
+ * This class is responsible for rendering text decorations like
+ * underline, strikethrough, text with background, etc.
+ */
+public class TextDecorator {
+    private static final TextDecorator inst = new TextDecorator();
+    private TextDecorator() {}
+    static TextDecorator getInstance() {
+        return inst;
+    }
+
+    /**
+     * This class encapsulates a set of decoration attributes for a single text run.
+     */
+    static class Decoration {
+        private static final BasicStroke UNDERLINE_LOW_ONE_PIXEL_STROKE =
+                new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10);
+
+        private static final BasicStroke UNDERLINE_LOW_TWO_PIXEL_STROKE =
+                new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10);
+
+        private static final BasicStroke UNDERLINE_LOW_DOTTED_STROKE =
+                new BasicStroke(
+                        1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
+                        new float[] { 1, 1 }, 0
+                );
+
+        private static final BasicStroke UNDERLINE_LOW_DOTTED_STROKE2 =
+                new BasicStroke(
+                        1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
+                        new float[] { 1, 1 }, 1
+                );
+
+        private static final BasicStroke UNDERLINE_LOW_DASHED_STROKE =
+                new BasicStroke(
+                        1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10,
+                        new float[] { 4, 4 }, 0
+                );
+
+        boolean ulOn = false; // Have standard underline?
+        BasicStroke ulStroke;
+
+        BasicStroke imUlStroke;  // Stroke for INPUT_METHOD_UNDERLINE
+        BasicStroke imUlStroke2; // Specially for UNDERLINE_LOW_GRAY
+
+        boolean strikeThrough;
+        BasicStroke strikeThroughStroke;
+
+        boolean haveStrokes = false; // Strokes already created?
+
+        boolean swapBfFg;
+        Paint bg; // background color
+        Paint fg; // foreground color
+
+        Paint graphicsPaint; // Slot for saving current paint
+
+        Decoration(
+                Integer imUl,
+                boolean swap,
+                boolean sth,
+                Paint bg, Paint fg,
+                boolean ulOn) {
+
+            if (imUl != null) {
+                // Determine which stroke to use
+                if (imUl == TextAttribute.UNDERLINE_LOW_ONE_PIXEL) {
+                    this.imUlStroke = Decoration.UNDERLINE_LOW_ONE_PIXEL_STROKE;
+                } else if (imUl == TextAttribute.UNDERLINE_LOW_TWO_PIXEL) {
+                    this.imUlStroke = Decoration.UNDERLINE_LOW_TWO_PIXEL_STROKE;
+                } else if (imUl == TextAttribute.UNDERLINE_LOW_DOTTED) {
+                    this.imUlStroke = Decoration.UNDERLINE_LOW_DOTTED_STROKE;
+                } else if (imUl == TextAttribute.UNDERLINE_LOW_GRAY) {
+                    this.imUlStroke = Decoration.UNDERLINE_LOW_DOTTED_STROKE;
+                    this.imUlStroke2 = Decoration.UNDERLINE_LOW_DOTTED_STROKE2;
+                } else if (imUl == TextAttribute.UNDERLINE_LOW_DASHED) {
+                    this.imUlStroke = Decoration.UNDERLINE_LOW_DASHED_STROKE;
+                }
+            }
+
+            this.ulOn = ulOn; // Has underline
+            this.swapBfFg = swap;
+            this.strikeThrough = sth;
+            this.bg = bg;
+            this.fg = fg;
+        }
+
+        /**
+         * Creates strokes of proper width according to the info
+         * stored in the BasicMetrics
+         * @param metrics - basic metrics
+         */
+        private void getStrokes(BasicMetrics metrics) {
+            if (!haveStrokes) {
+                if (strikeThrough) {
+                    strikeThroughStroke =
+                            new BasicStroke(
+                                    metrics.strikethroughThickness,
+                                    BasicStroke.CAP_BUTT,
+                                    BasicStroke.JOIN_MITER,
+                                    10
+                            );
+                }
+
+                if (ulOn) {
+                    ulStroke =
+                            new BasicStroke(
+                                    metrics.underlineThickness,
+                                    BasicStroke.CAP_BUTT,
+                                    BasicStroke.JOIN_MITER,
+                                    10
+                            );
+                }
+
+                haveStrokes = true;
+            }
+        }
+    }
+
+    /**
+     * Creates Decoration object from the set of text attributes
+     * @param attributes - text attributes
+     * @return Decoration object
+     */
+    static Decoration getDecoration(Map<? extends Attribute, ?> attributes) {
+        if (attributes == null) {
+            return null; // It is for plain text
+        }
+
+        Object underline = attributes.get(TextAttribute.UNDERLINE);
+        boolean hasStandardUnderline = underline == TextAttribute.UNDERLINE_ON;
+
+        Object imUnderline = attributes.get(TextAttribute.INPUT_METHOD_UNDERLINE);
+        Integer imUl = (Integer) imUnderline;
+
+        boolean swapBgFg =
+                TextAttribute.SWAP_COLORS_ON.equals(
+                        attributes.get(TextAttribute.SWAP_COLORS)
+                );
+
+        boolean strikeThrough =
+                TextAttribute.STRIKETHROUGH_ON.equals(
+                        attributes.get(TextAttribute.STRIKETHROUGH)
+                );
+
+        Paint fg = (Paint) attributes.get(TextAttribute.FOREGROUND);
+        Paint bg = (Paint) attributes.get(TextAttribute.BACKGROUND);
+
+        if (
+                !hasStandardUnderline &&
+                imUnderline == null &&
+                fg == null &&
+                bg == null &&
+                !swapBgFg &&
+                !strikeThrough
+        ) {
+            return null;
+        }
+        return new Decoration(imUl, swapBgFg, strikeThrough, bg, fg, hasStandardUnderline);
+    }
+
+    /**
+     * Fills the background before drawing if needed.
+     * 
+     * @param trs - text segment
+     * @param g2d - graphics to draw to
+     * @param xOffset - offset in X direction to the upper left corner of the
+     *        layout from the origin of the graphics
+     * @param yOffset - offset in Y direction to the upper left corner of the
+     *        layout from the origin of the graphics
+     */
+    static void prepareGraphics(
+            TextRunSegment trs, Graphics2D g2d,
+            float xOffset, float yOffset
+    ) {
+        Decoration d = trs.decoration;
+
+        if (d.fg == null && d.bg == null && d.swapBfFg == false) {
+            return; // Nothing to do
+        }
+
+        d.graphicsPaint = g2d.getPaint();
+
+        if (d.fg == null) {
+            d.fg = d.graphicsPaint;
+        }
+
+        if (d.swapBfFg) {
+            // Fill background area
+            g2d.setPaint(d.fg);
+            Rectangle2D bgArea = trs.getLogicalBounds();
+            Rectangle2D toFill =
+                    new Rectangle2D.Double(
+                            bgArea.getX() + xOffset,
+                            bgArea.getY() + yOffset,
+                            bgArea.getWidth(),
+                            bgArea.getHeight()
+                    );
+            g2d.fill(toFill);
+
+            // Set foreground color
+            g2d.setPaint(d.bg == null ? Color.WHITE : d.bg);
+        } else {
+            if (d.bg != null) { // Fill background area
+                g2d.setPaint(d.bg);
+                Rectangle2D bgArea = trs.getLogicalBounds();
+                Rectangle2D toFill =
+                        new Rectangle2D.Double(
+                                bgArea.getX() + xOffset,
+                                bgArea.getY() + yOffset,
+                                bgArea.getWidth(),
+                                bgArea.getHeight()
+                        );
+                g2d.fill(toFill);
+            }
+
+            // Set foreground color
+            g2d.setPaint(d.fg);
+        }
+    }
+
+    /**
+     * Restores the original state of the graphics if needed
+     * @param d - decoration
+     * @param g2d - graphics
+     */
+    static void restoreGraphics(Decoration d, Graphics2D g2d) {
+        if (d.fg == null && d.bg == null && d.swapBfFg == false) {
+            return; // Nothing to do
+        }
+
+        g2d.setPaint(d.graphicsPaint);
+    }
+
+    /**
+     * Renders the text decorations
+     * @param trs - text run segment
+     * @param g2d - graphics to render to
+     * @param xOffset - offset in X direction to the upper left corner
+     * of the layout from the origin of the graphics
+     * @param yOffset - offset in Y direction to the upper left corner
+     * of the layout from the origin of the graphics
+     */
+    static void drawTextDecorations(
+            TextRunSegment trs, Graphics2D g2d,
+            float xOffset, float yOffset
+    ) {
+        Decoration d = trs.decoration;
+
+        if (!d.ulOn && d.imUlStroke == null && !d.strikeThrough) {
+            return; // Nothing to do
+        }
+
+        float left = xOffset + (float) trs.getLogicalBounds().getMinX();
+        float right = xOffset + (float) trs.getLogicalBounds().getMaxX();
+
+        Stroke savedStroke = g2d.getStroke();
+
+        d.getStrokes(trs.metrics);
+
+        if (d.strikeThrough) {
+            float y = trs.y + yOffset + trs.metrics.strikethroughOffset;
+            g2d.setStroke(d.strikeThroughStroke);
+            g2d.draw(new Line2D.Float(left, y, right, y));
+        }
+
+        if (d.ulOn) {
+            float y = trs.y + yOffset + trs.metrics.underlineOffset;
+            g2d.setStroke(d.ulStroke);
+            g2d.draw(new Line2D.Float(left, y, right, y));
+        }
+
+        if (d.imUlStroke != null) {
+            float y = trs.y + yOffset + trs.metrics.underlineOffset;
+            g2d.setStroke(d.imUlStroke);
+            g2d.draw(new Line2D.Float(left, y, right, y));
+            if (d.imUlStroke2 != null) {
+                y++;
+                g2d.setStroke(d.imUlStroke2);
+                g2d.draw(new Line2D.Float(left, y, right, y));
+            }
+        }
+
+        g2d.setStroke(savedStroke);
+    }
+
+    /**
+     * Extends the visual bounds of the text run segment to
+     * include text decorations.
+     * @param trs - text segment
+     * @param segmentBounds - bounds of the undecorated text
+     * @param d - decoration
+     * @return extended bounds
+     */
+    static Rectangle2D extendVisualBounds(
+            TextRunSegment trs,
+            Rectangle2D segmentBounds,
+            Decoration d
+    ) {
+        if (d == null) {
+            return segmentBounds;
+        }
+        double minx = segmentBounds.getMinX();
+        double miny = segmentBounds.getMinY();
+        double maxx = segmentBounds.getMaxX();
+        double maxy = segmentBounds.getMaxY();
+
+        Rectangle2D lb = trs.getLogicalBounds();
+
+        if (d.swapBfFg || d.bg != null) {
+            minx = Math.min(lb.getMinX() - trs.x, minx);
+            miny = Math.min(lb.getMinY() - trs.y, miny);
+            maxx = Math.max(lb.getMaxX() - trs.x, maxx);
+            maxy = Math.max(lb.getMaxY() - trs.y, maxy);
+        }
+
+        if (d.ulOn || d.imUlStroke != null || d.strikeThrough) {
+            minx = Math.min(lb.getMinX() - trs.x, minx);
+            maxx = Math.max(lb.getMaxX() - trs.x, maxx);
+
+            d.getStrokes(trs.metrics);
+
+            if (d.ulStroke != null) {
+                maxy = Math.max(
+                        maxy,
+                        trs.metrics.underlineOffset +
+                        d.ulStroke.getLineWidth()
+                );
+            }
+
+            if (d.imUlStroke != null) {
+                maxy = Math.max(
+                        maxy,
+                        trs.metrics.underlineOffset +
+                        d.imUlStroke.getLineWidth() +
+                        (d.imUlStroke2 == null ? 0 : d.imUlStroke2.getLineWidth())
+                );
+            }
+        }
+
+        return new Rectangle2D.Double(minx, miny, maxx-minx, maxy-miny);
+    }
+
+    /**
+     * Extends the outline of the text run segment to
+     * include text decorations.
+     * @param trs - text segment
+     * @param segmentOutline - outline of the undecorated text
+     * @param d - decoration
+     * @return extended outline
+     */
+    static Shape extendOutline(
+            TextRunSegment trs,
+            Shape segmentOutline,
+            Decoration d
+    ) {
+        if (d == null || !d.ulOn && d.imUlStroke == null && !d.strikeThrough) {
+            return segmentOutline; // Nothing to do
+        }
+
+        Area res = new Area(segmentOutline);
+
+        float left = (float) trs.getLogicalBounds().getMinX() - trs.x;
+        float right = (float) trs.getLogicalBounds().getMaxX() - trs.x;
+
+        d.getStrokes(trs.metrics);
+
+        if (d.strikeThrough) {
+            float y = trs.metrics.strikethroughOffset;
+            res.add(new Area(d.strikeThroughStroke.createStrokedShape(
+                    new Line2D.Float(left, y, right, y)
+            )));
+        }
+
+        if (d.ulOn) {
+            float y = trs.metrics.underlineOffset;
+            res.add(new Area(d.ulStroke.createStrokedShape(
+                    new Line2D.Float(left, y, right, y)
+            )));
+        }
+
+        if (d.imUlStroke != null) {
+            float y = trs.metrics.underlineOffset;
+            res.add(new Area(d.imUlStroke.createStrokedShape(
+                    new Line2D.Float(left, y, right, y)
+            )));
+
+            if (d.imUlStroke2 != null) {
+                y++;
+                res.add(new Area(d.imUlStroke2.createStrokedShape(
+                        new Line2D.Float(left, y, right, y)
+                )));
+            }
+        }
+
+        return res;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextMetricsCalculator.java b/awt/org/apache/harmony/awt/gl/font/TextMetricsCalculator.java
new file mode 100644
index 0000000..be5762a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/TextMetricsCalculator.java
@@ -0,0 +1,209 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.font.LineMetrics;
+import java.awt.font.GraphicAttribute;
+import java.awt.Font;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * This class operates with an arbitrary text string which can include
+ * any number of style, font and direction runs. It is responsible for computation
+ * of the text metrics, such as ascent, descent, leading and advance. Actually,
+ * each text run segment contains logic which allows it to compute its own metrics and
+ * responsibility of this class is to combine metrics for all segments included in the text,
+ * managed by the associated TextRunBreaker object.
+ */
+public class TextMetricsCalculator {
+    TextRunBreaker breaker; // Associated run breaker
+
+    // Metrics
+    float ascent = 0;
+    float descent = 0;
+    float leading = 0;
+    float advance = 0;
+
+    private float baselineOffsets[];
+    int baselineIndex;
+
+    public TextMetricsCalculator(TextRunBreaker breaker) {
+        this.breaker = breaker;
+        checkBaselines();
+    }
+
+    /**
+     * Returns either values cached by checkBaselines method or reasonable
+     * values for the TOP and BOTTOM alignments.
+     * @param baselineIndex - baseline index
+     * @return baseline offset
+     */
+    float getBaselineOffset(int baselineIndex) {
+        if (baselineIndex >= 0) {
+            return baselineOffsets[baselineIndex];
+        } else if (baselineIndex == GraphicAttribute.BOTTOM_ALIGNMENT) {
+            return descent;
+        } else if (baselineIndex == GraphicAttribute.TOP_ALIGNMENT) {
+            return -ascent;
+        } else {
+            // awt.3F=Invalid baseline index
+            throw new IllegalArgumentException(Messages.getString("awt.3F")); //$NON-NLS-1$
+        }
+    }
+
+    public float[] getBaselineOffsets() {
+        float ret[] = new float[baselineOffsets.length];
+        System.arraycopy(baselineOffsets, 0, ret, 0, baselineOffsets.length);
+        return ret;
+    }
+
+    /**
+     * Take baseline offsets from the first font or graphic attribute
+     * and normalizes them, than caches the results.
+     */
+    public void checkBaselines() {
+        // Take baseline offsets of the first font and normalize them
+        HashMap<Integer, Font> fonts = breaker.fonts;
+
+        Object val = fonts.get(new Integer(0));
+
+        if (val instanceof Font) {
+            Font firstFont = (Font) val;
+            LineMetrics lm = firstFont.getLineMetrics(breaker.text, 0, 1, breaker.frc);
+            baselineOffsets = lm.getBaselineOffsets();
+            baselineIndex = lm.getBaselineIndex();
+        } else if (val instanceof GraphicAttribute) {
+            // Get first graphic attribute and use it
+            GraphicAttribute ga = (GraphicAttribute) val;
+
+            int align = ga.getAlignment();
+
+            if (
+                    align == GraphicAttribute.TOP_ALIGNMENT ||
+                    align == GraphicAttribute.BOTTOM_ALIGNMENT
+            ) {
+                baselineIndex = GraphicAttribute.ROMAN_BASELINE;
+            } else {
+                baselineIndex = align;
+            }
+
+            baselineOffsets = new float[3];
+            baselineOffsets[0] = 0;
+            baselineOffsets[1] = (ga.getDescent() - ga.getAscent()) / 2.f;
+            baselineOffsets[2] = -ga.getAscent();
+        } else { // Use defaults - Roman baseline and zero offsets
+            baselineIndex = GraphicAttribute.ROMAN_BASELINE;
+            baselineOffsets = new float[3];
+        }
+
+        // Normalize offsets if needed
+        if (baselineOffsets[baselineIndex] != 0) {
+            float baseOffset = baselineOffsets[baselineIndex];
+            for (int i = 0; i < baselineOffsets.length; i++) {
+                baselineOffsets[i] -= baseOffset;
+            }
+        }
+    }
+
+    /**
+     * Computes metrics for the text managed by the associated TextRunBreaker
+     */
+    void computeMetrics() {
+
+        ArrayList<TextRunSegment> segments = breaker.runSegments;
+
+        float maxHeight = 0;
+        float maxHeightLeading = 0;
+
+        for (int i = 0; i < segments.size(); i++) {
+            TextRunSegment segment = segments.get(i);
+            BasicMetrics metrics = segment.metrics;
+            int baseline = metrics.baseLineIndex;
+
+            if (baseline >= 0) {
+                float baselineOffset = baselineOffsets[metrics.baseLineIndex];
+                float fixedDescent = metrics.descent + baselineOffset;
+
+                ascent = Math.max(ascent, metrics.ascent - baselineOffset);
+                descent = Math.max(descent, fixedDescent);
+                leading = Math.max(leading, fixedDescent + metrics.leading);
+            } else { // Position is not fixed by the baseline, need sum of ascent and descent
+                float height = metrics.ascent + metrics.descent;
+
+                maxHeight = Math.max(maxHeight, height);
+                maxHeightLeading = Math.max(maxHeightLeading, height + metrics.leading);
+            }
+        }
+
+        // Need to increase sizes for graphics?
+        if (maxHeightLeading != 0) {
+            descent = Math.max(descent, maxHeight - ascent);
+            leading = Math.max(leading, maxHeightLeading - ascent);
+        }
+
+        // Normalize leading
+        leading -= descent;
+
+        BasicMetrics currMetrics;
+        float currAdvance = 0;
+
+        for (int i = 0; i < segments.size(); i++) {
+            TextRunSegment segment = segments.get(breaker.getSegmentFromVisualOrder(i));
+            currMetrics = segment.metrics;
+
+            segment.y = getBaselineOffset(currMetrics.baseLineIndex)
+                    + currMetrics.superScriptOffset;
+            segment.x = currAdvance;
+
+            currAdvance += segment.getAdvance();
+        }
+
+        advance = currAdvance;
+    }
+
+    /**
+     * Computes metrics and creates BasicMetrics object from them
+     * @return basic metrics
+     */
+    public BasicMetrics createMetrics() {
+        computeMetrics();
+        return new BasicMetrics(this);
+    }
+
+    /**
+     * Corrects advance after justification. Gets BasicMetrics object
+     * and updates advance stored into it.
+     * @param metrics - metrics with outdated advance which should be corrected 
+     */
+    public void correctAdvance(BasicMetrics metrics) {
+        ArrayList<TextRunSegment> segments = breaker.runSegments;
+        TextRunSegment segment = segments.get(breaker
+                .getSegmentFromVisualOrder(segments.size() - 1));
+
+        advance = segment.x + segment.getAdvance();
+        metrics.advance = advance;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextRunBreaker.java b/awt/org/apache/harmony/awt/gl/font/TextRunBreaker.java
new file mode 100644
index 0000000..be606f7
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/TextRunBreaker.java
@@ -0,0 +1,861 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
+import java.awt.im.InputMethodHighlight;
+import java.awt.font.*;
+import java.awt.*;
+import java.text.AttributedCharacterIterator;
+import java.text.Annotation;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.*;
+
+import org.apache.harmony.awt.gl.font.TextDecorator.Decoration;
+import org.apache.harmony.awt.internal.nls.Messages;
+import org.apache.harmony.misc.HashCode;
+// TODO - bidi not implemented yet
+
+/**
+ * This class is responsible for breaking the text into the run segments
+ * with constant font, style, other text attributes and direction.
+ * It also stores the created text run segments and covers functionality
+ * related to the operations on the set of segments, like calculating metrics,
+ * rendering, justification, hit testing, etc.
+ */
+public class TextRunBreaker implements Cloneable {
+    AttributedCharacterIterator aci;
+    FontRenderContext frc;
+
+    char[] text;
+
+    byte[] levels;
+
+    HashMap<Integer, Font> fonts;
+    HashMap<Integer, Decoration> decorations;
+
+    // Related to default font substitution
+    int forcedFontRunStarts[];
+
+    ArrayList<TextRunSegment> runSegments = new ArrayList<TextRunSegment>();
+
+    // For fast retrieving of the segment containing
+    // character with known logical index
+    int logical2segment[];
+    int segment2visual[]; // Visual order of segments TODO - implement
+    int visual2segment[];
+    int logical2visual[];
+    int visual2logical[];
+
+    SegmentsInfo storedSegments;
+    private boolean haveAllSegments = false;
+    int segmentsStart, segmentsEnd;
+
+    float justification = 1.0f;
+
+    public TextRunBreaker(AttributedCharacterIterator aci, FontRenderContext frc) {
+        this.aci = aci;
+        this.frc = frc;
+
+        segmentsStart = aci.getBeginIndex();
+        segmentsEnd = aci.getEndIndex();
+
+        int len = segmentsEnd - segmentsStart;
+        text = new char[len];
+        aci.setIndex(segmentsEnd);
+        while (len-- != 0) { // Going in backward direction is faster? Simplier checks here?
+            text[len] = aci.previous();
+        }
+
+        createStyleRuns();
+    }
+
+    /**
+     * Visual order of text segments may differ from the logical order.
+     * This method calculates visual position of the segment from its logical position.
+     * @param segmentNum - logical position of the segment
+     * @return visual position of the segment
+     */
+    int getVisualFromSegmentOrder(int segmentNum) {
+        return (segment2visual == null) ? segmentNum : segment2visual[segmentNum];
+    }
+
+    /**
+     * Visual order of text segments may differ from the logical order.
+     * This method calculates logical position of the segment from its visual position.
+     * @param visual - visual position of the segment
+     * @return logical position of the segment
+     */
+    int getSegmentFromVisualOrder(int visual) {
+        return (visual2segment == null) ? visual : visual2segment[visual];
+    }
+
+    /**
+     * Visual order of the characters may differ from the logical order.
+     * This method calculates visual position of the character from its logical position.
+     * @param logical - logical position of the character
+     * @return visual position
+     */
+    int getVisualFromLogical(int logical) {
+        return (logical2visual == null) ? logical : logical2visual[logical];
+    }
+
+    /**
+     * Visual order of the characters may differ from the logical order.
+     * This method calculates logical position of the character from its visual position.
+     * @param visual - visual position
+     * @return logical position
+     */
+    int getLogicalFromVisual(int visual) {
+        return (visual2logical == null) ? visual : visual2logical[visual];
+    }
+
+    /**
+     * Calculates the end index of the level run, limited by the given text run.
+     * @param runStart - run start
+     * @param runEnd - run end
+     * @return end index of the level run
+     */
+    int getLevelRunLimit(int runStart, int runEnd) {
+        if (levels == null) {
+            return runEnd;
+        }
+        int endLevelRun = runStart + 1;
+        byte level = levels[runStart];
+
+        while (endLevelRun <= runEnd && levels[endLevelRun] == level) {
+            endLevelRun++;
+        }
+
+        return endLevelRun;
+    }
+
+    /**
+     * Adds InputMethodHighlight to the attributes
+     * @param attrs - text attributes
+     * @return patched text attributes
+     */
+    Map<? extends Attribute, ?> unpackAttributes(Map<? extends Attribute, ?> attrs) {
+        if (attrs.containsKey(TextAttribute.INPUT_METHOD_HIGHLIGHT)) {
+            Map<TextAttribute, ?> styles = null;
+
+            Object val = attrs.get(TextAttribute.INPUT_METHOD_HIGHLIGHT);
+
+            if (val instanceof Annotation) {
+                val = ((Annotation) val).getValue();
+            }
+
+            if (val instanceof InputMethodHighlight) {
+                InputMethodHighlight ihl = ((InputMethodHighlight) val);
+                styles = ihl.getStyle();
+
+                if (styles == null) {
+                    Toolkit tk = Toolkit.getDefaultToolkit();
+                    styles = tk.mapInputMethodHighlight(ihl);
+                }
+            }
+
+            if (styles != null) {
+                HashMap<Attribute, Object> newAttrs = new HashMap<Attribute, Object>();
+                newAttrs.putAll(attrs);
+                newAttrs.putAll(styles);
+                return newAttrs;
+            }
+        }
+
+        return attrs;
+    }
+
+    /**
+     * Breaks the text into separate style runs.
+     */
+    void createStyleRuns() {
+        // TODO - implement fast and simple case
+        fonts = new HashMap<Integer, Font>();
+        decorations = new HashMap<Integer, Decoration>();
+        ////
+
+        ArrayList<Integer> forcedFontRunStartsList = null;
+
+        Map<? extends Attribute, ?> attributes = null;
+
+        // Check justification attribute
+        Object val = aci.getAttribute(TextAttribute.JUSTIFICATION);
+        if (val != null) {
+            justification = ((Float) val).floatValue();
+        }
+
+        for (
+            int index = segmentsStart, nextRunStart = segmentsStart;
+            index < segmentsEnd;
+            index = nextRunStart, aci.setIndex(index)
+           )  {
+            nextRunStart = aci.getRunLimit();
+            attributes = unpackAttributes(aci.getAttributes());
+
+            TextDecorator.Decoration d = TextDecorator.getDecoration(attributes);
+            decorations.put(new Integer(index), d);
+
+            // Find appropriate font or place GraphicAttribute there
+
+            // 1. Try to pick up CHAR_REPLACEMENT (compatibility)
+            Font value = (Font)attributes.get(TextAttribute.CHAR_REPLACEMENT);
+
+            if (value == null) {
+                // 2. Try to Get FONT
+                value = (Font)attributes.get(TextAttribute.FONT);
+
+                if (value == null) {
+                    // 3. Try to create font from FAMILY
+                    if (attributes.get(TextAttribute.FAMILY) != null) {
+                        value = Font.getFont(attributes);
+                    }
+
+                    if (value == null) {
+                        // 4. No attributes found, using default.
+                        if (forcedFontRunStartsList == null) {
+                            forcedFontRunStartsList = new ArrayList<Integer>();
+                        }
+                        FontFinder.findFonts(
+                                text,
+                                index,
+                                nextRunStart,
+                                forcedFontRunStartsList,
+                                fonts
+                        );
+                        value = fonts.get(new Integer(index));
+                    }
+                }
+            }
+
+            fonts.put(new Integer(index), value);
+        }
+
+        // We have added some default fonts, so we have some extra runs in text
+        if (forcedFontRunStartsList != null) {
+            forcedFontRunStarts = new int[forcedFontRunStartsList.size()];
+            for (int i=0; i<forcedFontRunStartsList.size(); i++) {
+                forcedFontRunStarts[i] =
+                        forcedFontRunStartsList.get(i).intValue();
+            }
+        }
+    }
+
+    /**
+     * Starting from the current position looks for the end of the text run with
+     * constant text attributes.
+     * @param runStart - start position
+     * @param maxPos - position where to stop if no run limit found
+     * @return style run limit
+     */
+    int getStyleRunLimit(int runStart, int maxPos) {
+        try {
+            aci.setIndex(runStart);
+        } catch(IllegalArgumentException e) { // Index out of bounds
+            if (runStart < segmentsStart) {
+                aci.first();
+            } else {
+                aci.last();
+            }
+        }
+
+        // If we have some extra runs we need to check for their limits
+        if (forcedFontRunStarts != null) {
+            for (int element : forcedFontRunStarts) {
+                if (element > runStart) {
+                    maxPos = Math.min(element, maxPos);
+                    break;
+                }
+            }
+        }
+
+        return Math.min(aci.getRunLimit(), maxPos);
+    }
+
+    /**
+     * Creates segments for the text run with
+     * constant decoration, font and bidi level
+     * @param runStart - run start
+     * @param runEnd - run end
+     */
+    public void createSegments(int runStart, int runEnd) {
+        int endStyleRun, endLevelRun;
+
+        // TODO - update levels
+
+        int pos = runStart, levelPos;
+
+        aci.setIndex(pos);
+        final int firstRunStart = aci.getRunStart();
+        Object tdd = decorations.get(new Integer(firstRunStart));
+        Object fontOrGAttr = fonts.get(new Integer(firstRunStart));
+
+        logical2segment = new int[runEnd - runStart];
+
+        do {
+            endStyleRun = getStyleRunLimit(pos, runEnd);
+
+            // runStart can be non-zero, but all arrays will be indexed from 0
+            int ajustedPos = pos - runStart;
+            int ajustedEndStyleRun = endStyleRun - runStart;
+            levelPos = ajustedPos;
+            do {
+                endLevelRun = getLevelRunLimit(levelPos, ajustedEndStyleRun);
+
+                if (fontOrGAttr instanceof GraphicAttribute) {
+                    runSegments.add(
+                        new TextRunSegmentImpl.TextRunSegmentGraphic(
+                                (GraphicAttribute)fontOrGAttr,
+                                endLevelRun - levelPos,
+                                levelPos + runStart)
+                    );
+                    Arrays.fill(logical2segment, levelPos, endLevelRun, runSegments.size()-1);
+                } else {
+                    TextRunSegmentImpl.TextSegmentInfo i =
+                            new TextRunSegmentImpl.TextSegmentInfo(
+                                    levels == null ? 0 : levels[ajustedPos],
+                                    (Font) fontOrGAttr,
+                                    frc,
+                                    text,
+                                    levelPos + runStart,
+                                    endLevelRun + runStart
+                            );
+
+                    runSegments.add(
+                            new TextRunSegmentImpl.TextRunSegmentCommon(
+                                    i,
+                                    (TextDecorator.Decoration) tdd
+                            )
+                    );
+                    Arrays.fill(logical2segment, levelPos, endLevelRun, runSegments.size()-1);
+                }
+
+                levelPos = endLevelRun;
+            } while (levelPos < ajustedEndStyleRun);
+
+            // Prepare next iteration
+            pos = endStyleRun;
+            tdd = decorations.get(new Integer(pos));
+            fontOrGAttr = fonts.get(new Integer(pos));
+        } while (pos < runEnd);
+    }
+
+    /**
+     * Checks if text run segments are up to date and creates the new segments if not.
+     */
+    public void createAllSegments() {
+        if ( !haveAllSegments &&
+            (logical2segment == null ||
+             logical2segment.length != segmentsEnd - segmentsStart)
+        ) { // Check if we don't have all segments yet
+            resetSegments();
+            createSegments(segmentsStart, segmentsEnd);
+        }
+
+        haveAllSegments = true;
+    }
+
+    /**
+     * Calculates position where line should be broken without
+     * taking into account word boundaries.
+     * @param start - start index
+     * @param maxAdvance - maximum advance, width of the line
+     * @return position where to break
+     */
+    public int getLineBreakIndex(int start, float maxAdvance) {
+        int breakIndex;
+        TextRunSegment s = null;
+
+        for (
+                int segmentIndex = logical2segment[start];
+                segmentIndex < runSegments.size();
+                segmentIndex++
+           ) {
+            s = runSegments.get(segmentIndex);
+            breakIndex = s.getCharIndexFromAdvance(maxAdvance, start);
+
+            if (breakIndex < s.getEnd()) {
+                return breakIndex;
+            }
+            maxAdvance -= s.getAdvanceDelta(start, s.getEnd());
+            start = s.getEnd();
+        }
+
+        return s.getEnd();
+    }
+
+    /**
+     * Inserts character into the managed text.
+     * @param newParagraph - new character iterator
+     * @param insertPos - insertion position
+     */
+    public void insertChar(AttributedCharacterIterator newParagraph, int insertPos) {
+        aci = newParagraph;
+
+        char insChar = aci.setIndex(insertPos);
+
+        Integer key = new Integer(insertPos);
+
+        insertPos -= aci.getBeginIndex();
+
+        char newText[] = new char[text.length + 1];
+        System.arraycopy(text, 0, newText, 0, insertPos);
+        newText[insertPos] = insChar;
+        System.arraycopy(text, insertPos, newText, insertPos+1, text.length - insertPos);
+        text = newText;
+
+        if (aci.getRunStart() == key.intValue() && aci.getRunLimit() == key.intValue() + 1) {
+            createStyleRuns(); // We have to create one new run, could be optimized
+        } else {
+            shiftStyleRuns(key, 1);
+        }
+
+        resetSegments();
+
+        segmentsEnd++;
+    }
+
+    /**
+     * Deletes character from the managed text.
+     * @param newParagraph - new character iterator
+     * @param deletePos - deletion position
+     */
+    public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos) {
+        aci = newParagraph;
+
+        Integer key = new Integer(deletePos);
+
+        deletePos -= aci.getBeginIndex();
+
+        char newText[] = new char[text.length - 1];
+        System.arraycopy(text, 0, newText, 0, deletePos);
+        System.arraycopy(text, deletePos+1, newText, deletePos, newText.length - deletePos);
+        text = newText;
+
+        if (fonts.get(key) != null) {
+            fonts.remove(key);
+        }
+
+        shiftStyleRuns(key, -1);
+
+        resetSegments();
+
+        segmentsEnd--;
+    }
+
+    /**
+     * Shift all runs after specified position, needed to perfom insertion
+     * or deletion in the managed text
+     * @param pos - position where to start
+     * @param shift - shift, could be negative
+     */
+    private void shiftStyleRuns(Integer pos, final int shift) {
+        ArrayList<Integer> keys = new ArrayList<Integer>();
+
+        Integer key, oldkey;
+        for (Iterator<Integer> it = fonts.keySet().iterator(); it.hasNext(); ) {
+            oldkey = it.next();
+            if (oldkey.intValue() > pos.intValue()) {
+                keys.add(oldkey);
+            }
+        }
+
+        for (int i=0; i<keys.size(); i++) {
+            oldkey = keys.get(i);
+            key = new Integer(shift + oldkey.intValue());
+            fonts.put(key, fonts.remove(oldkey));
+            decorations.put(key, decorations.remove(oldkey));
+        }
+    }
+
+    /**
+     * Resets state of the class
+     */
+    private void resetSegments() {
+        runSegments = new ArrayList<TextRunSegment>();
+        logical2segment = null;
+        segment2visual = null;
+        visual2segment = null;
+        levels = null;
+        haveAllSegments = false;
+    }
+
+    private class SegmentsInfo {
+        ArrayList<TextRunSegment> runSegments;
+        int logical2segment[];
+        int segment2visual[];
+        int visual2segment[];
+        byte levels[];
+        int segmentsStart;
+        int segmentsEnd;
+    }
+
+    /**
+     * Saves the internal state of the class
+     * @param newSegStart - new start index in the text
+     * @param newSegEnd - new end index in the text
+     */
+    public void pushSegments(int newSegStart, int newSegEnd) {
+        storedSegments = new SegmentsInfo();
+        storedSegments.runSegments = this.runSegments;
+        storedSegments.logical2segment = this.logical2segment;
+        storedSegments.segment2visual = this.segment2visual;
+        storedSegments.visual2segment = this.visual2segment;
+        storedSegments.levels = this.levels;
+        storedSegments.segmentsStart = segmentsStart;
+        storedSegments.segmentsEnd = segmentsEnd;
+
+        resetSegments();
+
+        segmentsStart = newSegStart;
+        segmentsEnd = newSegEnd;
+    }
+
+    /**
+     * Restores the internal state of the class
+     */
+    public void popSegments() {
+        if (storedSegments == null) {
+            return;
+        }
+
+        this.runSegments = storedSegments.runSegments;
+        this.logical2segment = storedSegments.logical2segment;
+        this.segment2visual = storedSegments.segment2visual;
+        this.visual2segment = storedSegments.visual2segment;
+        this.levels = storedSegments.levels;
+        this.segmentsStart = storedSegments.segmentsStart;
+        this.segmentsEnd = storedSegments.segmentsEnd;
+        storedSegments = null;
+
+        if (runSegments.size() == 0 && logical2segment == null) {
+            haveAllSegments = false;
+        } else {
+            haveAllSegments = true;
+        }
+    }
+
+    @Override
+    public Object clone() {
+        try {
+            TextRunBreaker res = (TextRunBreaker) super.clone();
+            res.storedSegments = null;
+            ArrayList<TextRunSegment> newSegments = new ArrayList<TextRunSegment>(runSegments.size());
+            for (int i = 0; i < runSegments.size(); i++) {
+                TextRunSegment seg =  runSegments.get(i);
+                newSegments.add((TextRunSegment)seg.clone());
+            }
+            res.runSegments = newSegments;
+            return res;
+        } catch (CloneNotSupportedException e) {
+            // awt.3E=Clone not supported
+            throw new UnsupportedOperationException(Messages.getString("awt.3E")); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof TextRunBreaker)) {
+            return false;
+        }
+
+        TextRunBreaker br = (TextRunBreaker) obj;
+
+        if (br.getACI().equals(aci) && br.frc.equals(frc)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashCode.combine(aci.hashCode(), frc.hashCode());
+    }
+
+    /**
+     * Renders the managed text
+     * @param g2d - graphics where to render
+     * @param xOffset - offset in X direction to the upper left corner
+     * of the layout from the origin of the graphics
+     * @param yOffset - offset in Y direction to the upper left corner
+     * of the layout from the origin of the graphics
+     */
+    public void drawSegments(Graphics2D g2d, float xOffset, float yOffset) {
+        for (int i=0; i<runSegments.size(); i++) {
+            runSegments.get(i).draw(g2d, xOffset, yOffset);
+        }
+    }
+
+    /**
+     * Creates the black box bounds shape
+     * @param firstEndpoint - start position
+     * @param secondEndpoint - end position
+     * @return black box bounds shape
+     */
+    public Shape getBlackBoxBounds(int firstEndpoint, int secondEndpoint) {
+        GeneralPath bounds = new GeneralPath();
+
+        TextRunSegment segment;
+
+        for (int idx = firstEndpoint; idx < secondEndpoint; idx=segment.getEnd()) {
+            segment = runSegments.get(logical2segment[idx]);
+            bounds.append(segment.getCharsBlackBoxBounds(idx, secondEndpoint), false);
+        }
+
+        return bounds;
+    }
+
+    /**
+     * Creates visual bounds shape
+     * @return visual bounds rectangle
+     */
+    public Rectangle2D getVisualBounds() {
+        Rectangle2D bounds = null;
+
+        for (int i=0; i<runSegments.size(); i++) {
+            TextRunSegment s = runSegments.get(i);
+            if (bounds != null) {
+                Rectangle2D.union(bounds, s.getVisualBounds(), bounds);
+            } else {
+                bounds = s.getVisualBounds();
+            }
+        }
+
+        return bounds;
+    }
+
+    /**
+     * Creates logical bounds shape
+     * @return logical bounds rectangle
+     */
+    public Rectangle2D getLogicalBounds() {
+        Rectangle2D bounds = null;
+
+        for (int i=0; i<runSegments.size(); i++) {
+            TextRunSegment s = runSegments.get(i);
+            if (bounds != null) {
+                Rectangle2D.union(bounds, s.getLogicalBounds(), bounds);
+            } else {
+                bounds = s.getLogicalBounds();
+            }
+        }
+
+        return bounds;
+    }
+
+    public int getCharCount() {
+        return segmentsEnd - segmentsStart;
+    }
+
+    public byte getLevel(int idx) {
+        if (levels == null) {
+            return 0;
+        }
+        return levels[idx];
+    }
+
+    public int getBaseLevel() {
+        return 0;
+    }
+
+    public boolean isLTR() {
+        return true;
+    }
+
+    public char getChar(int index) {
+        return text[index];
+    }
+
+    public AttributedCharacterIterator getACI() {
+        return aci;
+    }
+
+    /**
+     * Creates outline shape for the managed text
+     * @return outline
+     */
+    public GeneralPath getOutline() {
+        GeneralPath outline = new GeneralPath();
+
+        TextRunSegment segment;
+
+        for (int i = 0; i < runSegments.size(); i++) {
+            segment = runSegments.get(i);
+            outline.append(segment.getOutline(), false);
+        }
+
+        return outline;
+    }
+
+    /**
+     * Calculates text hit info from the screen coordinates.
+     * Current implementation totally ignores Y coordinate.
+     * If X coordinate is outside of the layout boundaries, this
+     * method returns leftmost or rightmost hit.
+     * @param x - x coordinate of the hit
+     * @param y - y coordinate of the hit
+     * @return hit info
+     */
+    public TextHitInfo hitTest(float x, float y) {
+        TextRunSegment segment;
+
+        double endOfPrevSeg = -1;
+        for (int i = 0; i < runSegments.size(); i++) {
+            segment = runSegments.get(i);
+            Rectangle2D bounds = segment.getVisualBounds();
+            if ((bounds.getMinX() <= x && bounds.getMaxX() >= x) || // We are in the segment
+               (endOfPrevSeg < x && bounds.getMinX() > x)) { // We are somewhere between the segments
+                return segment.hitTest(x,y);
+            }
+            endOfPrevSeg = bounds.getMaxX();
+        }
+
+        return isLTR() ? TextHitInfo.trailing(text.length) : TextHitInfo.leading(0);
+    }
+
+    public float getJustification() {
+        return justification;
+    }
+
+    /**
+     * Calculates position of the last non whitespace character
+     * in the managed text.
+     * @return position of the last non whitespace character
+     */
+    public int getLastNonWhitespace() {
+        int lastNonWhitespace = text.length;
+
+        while (lastNonWhitespace >= 0) {
+            lastNonWhitespace--;
+            if (!Character.isWhitespace(text[lastNonWhitespace])) {
+                break;
+            }
+        }
+
+        return lastNonWhitespace;
+    }
+
+    /**
+     * Performs justification of the managed text by changing segment positions
+     * and positions of the glyphs inside of the segments.
+     * @param gap - amount of space which should be compensated by justification
+     */
+    public void justify(float gap) {
+        // Ignore trailing logical whitespace
+        int firstIdx = segmentsStart;
+        int lastIdx = getLastNonWhitespace() + segmentsStart;
+        JustificationInfo jInfos[] = new JustificationInfo[5];
+        float gapLeft = gap;
+
+        int highestPriority = -1;
+        // GlyphJustificationInfo.PRIORITY_KASHIDA is 0
+        // GlyphJustificationInfo.PRIORITY_NONE is 3
+        for (int priority = 0; priority <= GlyphJustificationInfo.PRIORITY_NONE + 1; priority++) {
+            JustificationInfo jInfo = new JustificationInfo();
+            jInfo.lastIdx = lastIdx;
+            jInfo.firstIdx = firstIdx;
+            jInfo.grow = gap > 0;
+            jInfo.gapToFill = gapLeft;
+
+            if (priority <= GlyphJustificationInfo.PRIORITY_NONE) {
+                jInfo.priority = priority;
+            } else {
+                jInfo.priority = highestPriority; // Last pass
+            }
+
+            for (int i = 0; i < runSegments.size(); i++) {
+                TextRunSegment segment = runSegments.get(i);
+                if (segment.getStart() <= lastIdx) {
+                    segment.updateJustificationInfo(jInfo);
+                }
+            }
+
+            if (jInfo.priority == highestPriority) {
+                jInfo.absorb = true;
+                jInfo.absorbedWeight = jInfo.weight;
+            }
+
+            if (jInfo.weight != 0) {
+                if (highestPriority < 0) {
+                    highestPriority = priority;
+                }
+                jInfos[priority] = jInfo;
+            } else {
+                continue;
+            }
+
+            gapLeft -= jInfo.growLimit;
+
+            if (((gapLeft > 0) ^ jInfo.grow) || gapLeft == 0) {
+                gapLeft = 0;
+                jInfo.gapPerUnit = jInfo.gapToFill/jInfo.weight;
+                break;
+            }
+            jInfo.useLimits = true;
+
+            if (jInfo.absorbedWeight > 0) {
+                jInfo.absorb = true;
+                jInfo.absorbedGapPerUnit =
+                        (jInfo.gapToFill-jInfo.growLimit)/jInfo.absorbedWeight;
+                break;
+            }
+        }
+
+        float currJustificationOffset = 0;
+        for (int i = 0; i < runSegments.size(); i++) {
+            TextRunSegment segment =
+                    runSegments.get(getSegmentFromVisualOrder(i));
+            segment.x += currJustificationOffset;
+            currJustificationOffset += segment.doJustification(jInfos);
+        }
+
+        justification = -1; // Make further justification impossible
+    }
+
+    /**
+     * This class represents the information collected before the actual
+     * justification is started and needed to perform the justification.
+     * This information is closely related to the information stored in the
+     * GlyphJustificationInfo for the text represented by glyph vectors.
+     */
+    class JustificationInfo {
+        boolean grow;
+        boolean absorb = false;
+        boolean useLimits = false;
+        int priority = 0;
+        float weight = 0;
+        float absorbedWeight = 0;
+        float growLimit = 0;
+
+        int lastIdx;
+        int firstIdx;
+
+        float gapToFill;
+
+        float gapPerUnit = 0; // Precalculated value, gapToFill / weight
+        float absorbedGapPerUnit = 0; // Precalculated value, gapToFill / weight
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextRunSegment.java b/awt/org/apache/harmony/awt/gl/font/TextRunSegment.java
new file mode 100644
index 0000000..1cd2c05
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/TextRunSegment.java
@@ -0,0 +1,165 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.font.TextHitInfo;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Abstract class which represents the segment of the text with constant attributes
+ * running in one direction (i.e. constant level).
+ */
+public abstract class TextRunSegment implements Cloneable {
+    float x; // Calculated x location of this segment on the screen
+    float y; // Calculated y location of this segment on the screen
+
+    BasicMetrics metrics; // Metrics of this text run segment
+    TextDecorator.Decoration decoration; // Underline, srikethrough, etc.
+    Rectangle2D logicalBounds = null; // Logical bounding box for the segment
+    Rectangle2D visualBounds = null; // Visual bounding box for the segment
+
+    /**
+     * Returns start index of the segment
+     * @return start index
+     */
+    abstract int getStart();
+
+    /**
+     * Returns end index of the segment
+     * @return end index
+     */
+    abstract int getEnd();
+
+    /**
+     * Returns the number of characters in the segment
+     * @return number of characters
+     */
+    abstract int getLength();
+
+    /**
+     * Renders this text run segment
+     * @param g2d - graphics to render to
+     * @param xOffset - X offset from the graphics origin to the
+     * origin of the text layout
+     * @param yOffset - Y offset from the graphics origin to the
+     * origin of the text layout
+     */
+    abstract void draw(Graphics2D g2d, float xOffset, float yOffset);
+
+    /**
+     * Creates black box bounds shape for the specified range
+     * @param start - range sart
+     * @param limit - range end
+     * @return black box bounds shape
+     */
+    abstract Shape getCharsBlackBoxBounds(int start, int limit);
+
+    /**
+     * Returns the outline shape
+     * @return outline
+     */
+    abstract Shape getOutline();
+
+    /**
+     * Returns visual bounds of this segment
+     * @return visual bounds
+     */
+    abstract Rectangle2D getVisualBounds();
+
+    /**
+     * Returns logical bounds of this segment
+     * @return logical bounds
+     */
+    abstract Rectangle2D getLogicalBounds();
+
+    /**
+     * Calculates advance of the segment
+     * @return advance
+     */
+    abstract float getAdvance();
+
+    /**
+     * Calculates advance delta between two characters
+     * @param start - 1st position
+     * @param end - 2nd position
+     * @return advance increment between specified positions
+     */
+    abstract float getAdvanceDelta(int start, int end);
+
+    /**
+     * Calculates index of the character which advance is equal to
+     * the given. If the given advance is greater then the segment
+     * advance it returns the position after the last character.
+     * @param advance - given advance
+     * @param start - character, from which to start measuring advance
+     * @return character index
+     */
+    abstract int getCharIndexFromAdvance(float advance, int start);
+
+    /**
+     * Checks if the character doesn't contribute to the text advance
+     * @param index - character index
+     * @return true if the character has zero advance
+     */
+    abstract boolean charHasZeroAdvance(int index);
+
+    /**
+     * Calculates position of the character on the screen
+     * @param index - character index
+     * @return X coordinate of the character position
+     */
+    abstract float getCharPosition(int index);
+
+    /**
+     * Returns the advance of the individual character
+     * @param index - character index
+     * @return character advance
+     */
+    abstract float getCharAdvance(int index);
+
+    /**
+     * Creates text hit info from the hit position
+     * @param x - X coordinate relative to the origin of the layout
+     * @param y - Y coordinate relative to the origin of the layout
+     * @return hit info
+     */
+    abstract TextHitInfo hitTest(float x, float y);
+
+    /**
+     * Collects justification information into JustificationInfo object
+     * @param jInfo - JustificationInfo object
+     */
+    abstract void updateJustificationInfo(TextRunBreaker.JustificationInfo jInfo);
+
+    /**
+     * Performs justification of the segment.
+     * Updates positions of individual characters.
+     * @param jInfos - justification information, gathered by the previous passes
+     * @return amount of growth or shrink of the segment
+     */    
+    abstract float doJustification(TextRunBreaker.JustificationInfo jInfos[]);
+
+    @Override
+    public abstract Object clone();
+}
diff --git a/awt/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java b/awt/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java
new file mode 100644
index 0000000..0ec2d05
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java
@@ -0,0 +1,979 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ */
+
+package org.apache.harmony.awt.gl.font;
+
+import java.awt.*;
+import java.awt.font.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+// XXX - TODO - bidi not implemented yet
+//import java.text.Bidi;
+import java.util.Arrays;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * Date: Apr 25, 2005
+ * Time: 4:33:18 PM
+ *
+ * This class contains the implementation of the behavior of the
+ * text run segment with constant text attributes and direction.
+ */
+public class TextRunSegmentImpl {
+
+    /**
+     * This class contains basic information required for creation
+     * of the glyph-based text run segment.
+     */
+    public static class TextSegmentInfo {
+        // XXX - TODO - bidi not implemented yet
+        //Bidi bidi;
+
+        Font font;
+        FontRenderContext frc;
+
+        char text[];
+
+        int start;
+        int end;
+        int length;
+
+        int flags = 0;
+
+        byte level = 0;
+
+        TextSegmentInfo(
+                byte level,
+                Font font, FontRenderContext frc,
+                char text[], int start, int end
+        ) {
+            this.font = font;
+            this.frc = frc;
+            this.text = text;
+            this.start = start;
+            this.end = end;
+            this.level = level;
+            length = end - start;
+        }
+    }
+
+    /**
+     * This class represents a simple text segment backed by the glyph vector
+     */
+    public static class TextRunSegmentCommon extends TextRunSegment {
+        TextSegmentInfo info;
+        private GlyphVector gv;
+        private float advanceIncrements[];
+        private int char2glyph[];
+        private GlyphJustificationInfo gjis[]; // Glyph justification info
+
+        TextRunSegmentCommon(TextSegmentInfo i, TextDecorator.Decoration d) {
+            // XXX - todo - check support bidi
+            i.flags &= ~0x09; // Clear bidi flags
+
+            if ((i.level & 0x1) != 0) {
+                i.flags |= Font.LAYOUT_RIGHT_TO_LEFT;
+            }
+
+            info = i;
+            this.decoration = d;
+
+            LineMetrics lm = i.font.getLineMetrics(i.text, i.start, i.end, i.frc);
+            this.metrics = new BasicMetrics(lm, i.font);
+
+            if (lm.getNumChars() != i.length) { // XXX todo - This should be handled
+                // awt.41=Font returned unsupported type of line metrics. This case is known, but not supported yet.
+                throw new UnsupportedOperationException(
+                        Messages.getString("awt.41")); //$NON-NLS-1$
+            }
+        }
+
+        @Override
+        public Object clone() {
+            return new TextRunSegmentCommon(info, decoration);
+        }
+
+        /**
+         * Creates glyph vector from the managed text if needed
+         * @return glyph vector
+         */
+        private GlyphVector getGlyphVector() {
+            if (gv==null) {
+                gv = info.font.layoutGlyphVector(
+                        info.frc,
+                        info.text,
+                        info.start,
+                        info.end - info.start, // NOTE: This parameter violates
+                                               // spec, it is count,
+                                               // not limit as spec states
+                        info.flags
+                );
+            }
+
+            return gv;
+        }
+
+        /**
+         * Renders this text run segment
+         * @param g2d - graphics to render to
+         * @param xOffset - X offset from the graphics origin to the
+         * origin of the text layout
+         * @param yOffset - Y offset from the graphics origin to the
+         * origin of the text layout
+         */
+        @Override
+        void draw(Graphics2D g2d, float xOffset, float yOffset) {
+            if (decoration == null) {
+                g2d.drawGlyphVector(getGlyphVector(), xOffset + x, yOffset + y);
+            } else {
+                TextDecorator.prepareGraphics(this, g2d, xOffset, yOffset);
+                g2d.drawGlyphVector(getGlyphVector(), xOffset + x, yOffset + y);
+                TextDecorator.drawTextDecorations(this, g2d, xOffset, yOffset);
+                TextDecorator.restoreGraphics(decoration, g2d);
+            }
+        }
+
+        /**
+         * Returns visual bounds of this segment
+         * @return visual bounds
+         */
+        @Override
+        Rectangle2D getVisualBounds() {
+            if (visualBounds == null) {
+                visualBounds =
+                        TextDecorator.extendVisualBounds(
+                                this,
+                                getGlyphVector().getVisualBounds(),
+                                decoration
+                        );
+
+                visualBounds.setRect(
+                        x + visualBounds.getX(),
+                        y + visualBounds.getY(),
+                        visualBounds.getWidth(),
+                        visualBounds.getHeight()
+                );
+            }
+
+            return (Rectangle2D) visualBounds.clone();
+        }
+
+        /**
+         * Returns logical bounds of this segment
+         * @return logical bounds
+         */
+        @Override
+        Rectangle2D getLogicalBounds() {
+            if (logicalBounds == null) {
+                logicalBounds = getGlyphVector().getLogicalBounds();
+
+                logicalBounds.setRect(
+                        x + logicalBounds.getX(),
+                        y + logicalBounds.getY(),
+                        logicalBounds.getWidth(),
+                        logicalBounds.getHeight()
+                );
+            }
+
+            return (Rectangle2D) logicalBounds.clone();
+        }
+
+        @Override
+        float getAdvance() {
+            return (float) getLogicalBounds().getWidth();
+        }
+
+        /**
+         * Attemts to map each character to the corresponding advance increment
+         */
+        void initAdvanceMapping() {
+            GlyphVector gv = getGlyphVector();
+            int charIndicies[] = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), null);
+            advanceIncrements = new float[info.length];
+
+            for (int i=0; i<charIndicies.length; i++) {
+                advanceIncrements[charIndicies[i]] = gv.getGlyphMetrics(i).getAdvance();
+            }
+        }
+
+        /**
+         * Calculates advance delta between two characters
+         * @param start - 1st position
+         * @param end - 2nd position
+         * @return advance increment between specified positions
+         */
+        @Override
+        float getAdvanceDelta(int start, int end) {
+            // Get coordinates in the segment context
+            start -= info.start;
+            end -= info.start;
+
+            if (advanceIncrements == null) {
+                initAdvanceMapping();
+            }
+
+            if (start < 0) {
+                start = 0;
+            }
+            if (end > info.length) {
+                end = info.length;
+            }
+
+            float sum = 0;
+            for (int i=start; i<end; i++) {
+                sum += advanceIncrements[i];
+            }
+
+            return sum;
+        }
+
+        /**
+         * Calculates index of the character which advance is equal to
+         * the given. If the given advance is greater then the segment
+         * advance it returns the position after the last character.
+         * @param advance - given advance
+         * @param start - character, from which to start measuring advance
+         * @return character index
+         */
+        @Override
+        int getCharIndexFromAdvance(float advance, int start) {
+            // XXX - todo - probably, possible to optimize
+            // Add check if the given advance is greater then
+            // the segment advance in the beginning. In this case
+            // we don't need to run through all increments
+            if (advanceIncrements == null) {
+                initAdvanceMapping();
+            }
+
+            start -= info.start;
+
+            if (start < 0) {
+                start = 0;
+            }
+
+            int i = start;
+            for (; i<info.length; i++) {
+                advance -= advanceIncrements[i];
+                if (advance < 0) {
+                    break;
+                }
+            }
+
+            return i + info.start;
+        }
+
+        @Override
+        int getStart() {
+            return info.start;
+        }
+
+        @Override
+        int getEnd() {
+            return info.end;
+        }
+
+        @Override
+        int getLength() {
+            return info.length;
+        }
+
+        /**
+         * Attemts to create mapping of the characters to glyphs in the glyph vector.
+         * @return array where for each character index stored corresponding glyph index
+         */
+        private int[] getChar2Glyph() {
+            if (char2glyph == null) {
+                GlyphVector gv = getGlyphVector();
+                char2glyph = new int[info.length];
+                Arrays.fill(char2glyph, -1);
+
+                // Fill glyph indicies for first characters corresponding to each glyph
+                int charIndicies[] = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), null);
+                for (int i=0; i<charIndicies.length; i++) {
+                    char2glyph[charIndicies[i]] = i;
+                }
+
+                // If several characters corresponds to one glyph, create mapping for them
+                // Suppose that these characters are going all together
+                int currIndex = 0;
+                for (int i=0; i<char2glyph.length; i++) {
+                    if (char2glyph[i] < 0) {
+                        char2glyph[i] = currIndex;
+                    } else {
+                        currIndex = char2glyph[i];
+                    }
+                }
+            }
+
+            return char2glyph;
+        }
+
+        /**
+         * Creates black box bounds shape for the specified range
+         * @param start - range sart
+         * @param limit - range end
+         * @return black box bounds shape
+         */
+        @Override
+        Shape getCharsBlackBoxBounds(int start, int limit) {
+            start -= info.start;
+            limit -= info.start;
+
+            if (limit > info.length) {
+                limit = info.length;
+            }
+
+            GeneralPath result = new GeneralPath();
+
+            int glyphIndex = 0;
+
+            for (int i=start; i<limit; i++) {
+                glyphIndex = getChar2Glyph()[i];
+                result.append(getGlyphVector().getGlyphVisualBounds(glyphIndex), false);
+            }
+
+            // Shift to the segment's coordinates
+            result.transform(AffineTransform.getTranslateInstance(x, y));
+
+            return result;
+        }
+
+        /**
+         * Calculates position of the character on the screen
+         * @param index - character index
+         * @return X coordinate of the character position
+         */
+        @Override
+        float getCharPosition(int index) {
+            index -= info.start;
+
+            if (index > info.length) {
+                index = info.length;
+            }
+
+            float result = 0;
+
+            int glyphIndex = getChar2Glyph()[index];
+            result = (float) getGlyphVector().getGlyphPosition(glyphIndex).getX();
+
+            // Shift to the segment's coordinates
+            result += x;
+
+            return result;
+        }
+
+        /**
+         * Returns the advance of the individual character
+         * @param index - character index
+         * @return character advance
+         */
+        @Override
+        float getCharAdvance(int index) {
+            if (advanceIncrements == null) {
+                initAdvanceMapping();
+            }
+
+            return advanceIncrements[index - this.getStart()];
+        }
+
+        /**
+         * Returns the outline shape
+         * @return outline
+         */
+        @Override
+        Shape getOutline() {
+            AffineTransform t = AffineTransform.getTranslateInstance(x, y);
+            return t.createTransformedShape(
+                    TextDecorator.extendOutline(
+                            this,
+                            getGlyphVector().getOutline(),
+                            decoration
+                    )
+            );
+        }
+
+        /**
+         * Checks if the character doesn't contribute to the text advance
+         * @param index - character index
+         * @return true if the character has zero advance
+         */
+        @Override
+        boolean charHasZeroAdvance(int index) {
+            if (advanceIncrements == null) {
+                initAdvanceMapping();
+            }
+
+            return advanceIncrements[index - this.getStart()] == 0;
+        }
+
+        /**
+         * Creates text hit info from the hit position
+         * @param hitX - X coordinate relative to the origin of the layout
+         * @param hitY - Y coordinate relative to the origin of the layout
+         * @return hit info
+         */
+        @Override
+        TextHitInfo hitTest(float hitX, float hitY) {
+            hitX -= x;
+
+            float glyphPositions[] =
+                    getGlyphVector().getGlyphPositions(0, info.length+1, null);
+
+            int glyphIdx;
+            boolean leading = false;
+            for (glyphIdx = 1; glyphIdx <= info.length; glyphIdx++) {
+                if (glyphPositions[(glyphIdx)*2] >= hitX) {
+                    float advance =
+                            glyphPositions[(glyphIdx)*2] - glyphPositions[(glyphIdx-1)*2];
+                    leading = glyphPositions[(glyphIdx-1)*2] + advance/2 > hitX ? true : false;
+                    glyphIdx--;
+                    break;
+                }
+            }
+
+            if (glyphIdx == info.length) {
+                glyphIdx--;
+            }
+
+            int charIdx = getGlyphVector().getGlyphCharIndex(glyphIdx);
+
+            return (leading) ^ ((info.level & 0x1) == 0x1)?
+                    TextHitInfo.leading(charIdx + info.start) :
+                    TextHitInfo.trailing(charIdx + info.start);
+        }
+
+        /**
+         * Collects GlyphJustificationInfo objects from the glyph vector
+         * @return array of all GlyphJustificationInfo objects
+         */
+        private GlyphJustificationInfo[] getGlyphJustificationInfos() {
+            if (gjis == null) {
+                GlyphVector gv = getGlyphVector();
+                int nGlyphs = gv.getNumGlyphs();
+                int charIndicies[] = gv.getGlyphCharIndices(0, nGlyphs, null);
+                gjis = new GlyphJustificationInfo[nGlyphs];
+
+                // Patch: temporary patch, getGlyphJustificationInfo is not implemented
+                float fontSize = info.font.getSize2D();
+                GlyphJustificationInfo defaultInfo =
+                        new GlyphJustificationInfo(
+                                0, // weight
+                                false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0, // grow
+                                false, GlyphJustificationInfo.PRIORITY_NONE, 0, 0); // shrink
+                GlyphJustificationInfo spaceInfo = new GlyphJustificationInfo(
+                        fontSize, // weight
+                        true, GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, fontSize, // grow
+                        true, GlyphJustificationInfo.PRIORITY_WHITESPACE, 0, fontSize); // shrink
+
+                ////////
+                // Temporary patch, getGlyphJustificationInfo is not implemented
+                for (int i = 0; i < nGlyphs; i++) {
+                    //gjis[i] = getGlyphVector().getGlyphJustificationInfo(i);
+
+                    char c = info.text[charIndicies[i] + info.start];
+                    if (Character.isWhitespace(c)) {
+                        gjis[i] = spaceInfo;
+                    } else {
+                        gjis[i] = defaultInfo;
+                    }
+                    // End patch
+                }
+            }
+
+            return gjis;
+        }
+
+        /**
+         * Collects justification information into JustificationInfo object
+         * @param jInfo - JustificationInfo object
+         */
+        @Override
+        void updateJustificationInfo(TextRunBreaker.JustificationInfo jInfo) {
+            int lastChar = Math.min(jInfo.lastIdx, info.end) - info.start;
+            boolean haveFirst = info.start <= jInfo.firstIdx;
+            boolean haveLast = info.end >= (jInfo.lastIdx + 1);
+
+            int prevGlyphIdx = -1;
+            int currGlyphIdx;
+
+            if (jInfo.grow) { // Check how much we can grow/shrink on current priority level
+                for (int i=0; i<lastChar; i++) {
+                    currGlyphIdx = getChar2Glyph()[i];
+
+                    if (currGlyphIdx == prevGlyphIdx) {
+                        // Several chars could be represented by one glyph,
+                        // suppose they are contiguous
+                        continue;
+                    }
+                    prevGlyphIdx = currGlyphIdx;
+
+                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[currGlyphIdx];
+                    if (gji.growPriority == jInfo.priority) {
+                        jInfo.weight += gji.weight * 2;
+                        jInfo.growLimit += gji.growLeftLimit;
+                        jInfo.growLimit += gji.growRightLimit;
+                        if (gji.growAbsorb) {
+                            jInfo.absorbedWeight += gji.weight * 2;
+                        }
+                    }
+                }
+            } else {
+                for (int i=0; i<lastChar; i++) {
+                    currGlyphIdx = getChar2Glyph()[i];
+                    if (currGlyphIdx == prevGlyphIdx) {
+                        continue;
+                    }
+                    prevGlyphIdx = currGlyphIdx;
+
+                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[currGlyphIdx];
+                    if (gji.shrinkPriority == jInfo.priority) {
+                        jInfo.weight += gji.weight * 2;
+                        jInfo.growLimit -= gji.shrinkLeftLimit;
+                        jInfo.growLimit -= gji.shrinkRightLimit;
+                        if (gji.shrinkAbsorb) {
+                            jInfo.absorbedWeight += gji.weight * 2;
+                        }
+                    }
+                }
+            }
+
+            if (haveFirst) {  // Don't add padding before first char
+                GlyphJustificationInfo gji = getGlyphJustificationInfos()[getChar2Glyph()[0]];
+                jInfo.weight -= gji.weight;
+                if (jInfo.grow) {
+                    jInfo.growLimit -= gji.growLeftLimit;
+                    if (gji.growAbsorb) {
+                        jInfo.absorbedWeight -= gji.weight;
+                    }
+                } else {
+                    jInfo.growLimit += gji.shrinkLeftLimit;
+                    if (gji.shrinkAbsorb) {
+                        jInfo.absorbedWeight -= gji.weight;
+                    }
+                }
+            }
+
+            if (haveLast) {   // Don't add padding after last char
+                GlyphJustificationInfo gji =
+                        getGlyphJustificationInfos()[getChar2Glyph()[lastChar]];
+                jInfo.weight -= gji.weight;
+                if (jInfo.grow) {
+                    jInfo.growLimit -= gji.growRightLimit;
+                    if (gji.growAbsorb) {
+                        jInfo.absorbedWeight -= gji.weight;
+                    }
+                } else {
+                    jInfo.growLimit += gji.shrinkRightLimit;
+                    if (gji.shrinkAbsorb) {
+                        jInfo.absorbedWeight -= gji.weight;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Performs justification of the segment.
+         * Updates positions of individual characters.
+         * @param jInfos - justification information, gathered by the previous passes
+         * @return amount of growth or shrink of the segment
+         */
+        @Override
+        float doJustification(TextRunBreaker.JustificationInfo jInfos[]) {
+            int lastPriority =
+                    jInfos[jInfos.length-1] == null ?
+                    -1 : jInfos[jInfos.length-1].priority;
+
+            // Get the highest priority
+            int highestPriority = 0;
+            for (; highestPriority<jInfos.length; highestPriority++) {
+                if (jInfos[highestPriority] != null) {
+                    break;
+                }
+            }
+
+            if (highestPriority == jInfos.length) {
+                return 0;
+            }
+
+            TextRunBreaker.JustificationInfo firstInfo = jInfos[highestPriority];
+            TextRunBreaker.JustificationInfo lastInfo =
+                    lastPriority > 0 ? jInfos[lastPriority] : null;
+
+            boolean haveFirst = info.start <= firstInfo.firstIdx;
+            boolean haveLast = info.end >= (firstInfo.lastIdx + 1);
+
+            // Here we suppose that GLYPHS are ordered LEFT TO RIGHT
+            int firstGlyph = haveFirst ?
+                    getChar2Glyph()[firstInfo.firstIdx - info.start] :
+                    getChar2Glyph()[0];
+
+            int lastGlyph = haveLast ?
+                    getChar2Glyph()[firstInfo.lastIdx - info.start] :
+                    getChar2Glyph()[info.length - 1];
+            if (haveLast) {
+                lastGlyph--;
+            }
+
+            TextRunBreaker.JustificationInfo currInfo;
+            float glyphOffset = 0;
+            float positionIncrement = 0;
+            float sideIncrement = 0;
+
+            if (haveFirst) {  // Don't add padding before first char
+                GlyphJustificationInfo gji = getGlyphJustificationInfos()[firstGlyph];
+                currInfo = jInfos[gji.growPriority];
+                if (currInfo != null) {
+                    if (currInfo.useLimits) {
+                        if (currInfo.absorb) {
+                            glyphOffset += gji.weight * currInfo.absorbedGapPerUnit;
+                        } else if (
+                                lastInfo != null &&
+                                lastInfo.priority == currInfo.priority
+                        ) {
+                            glyphOffset += gji.weight * lastInfo.absorbedGapPerUnit;
+                        }
+                        glyphOffset +=
+                                firstInfo.grow ?
+                                gji.growRightLimit :
+                                -gji.shrinkRightLimit;
+                    } else {
+                        glyphOffset += gji.weight * currInfo.gapPerUnit;
+                    }
+                }
+
+                firstGlyph++;
+            }
+
+            if (firstInfo.grow) {
+                for (int i=firstGlyph; i<=lastGlyph; i++) {
+                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[i];
+                    currInfo = jInfos[gji.growPriority];
+                    if (currInfo == null) {
+                        // We still have to increment glyph position
+                        Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
+                        glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
+                        getGlyphVector().setGlyphPosition(i, glyphPos);
+
+                        continue;
+                    }
+
+                    if (currInfo.useLimits) {
+                        glyphOffset += gji.growLeftLimit;
+                        if (currInfo.absorb) {
+                            sideIncrement = gji.weight * currInfo.absorbedGapPerUnit;
+                            glyphOffset += sideIncrement;
+                            positionIncrement = glyphOffset;
+                            glyphOffset += sideIncrement;
+                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
+                            sideIncrement = gji.weight * lastInfo.absorbedGapPerUnit;
+                            glyphOffset += sideIncrement;
+                            positionIncrement = glyphOffset;
+                            glyphOffset += sideIncrement;
+                        } else {
+                            positionIncrement = glyphOffset;
+                        }
+                        glyphOffset += gji.growRightLimit;
+                    } else {
+                        sideIncrement = gji.weight * currInfo.gapPerUnit;
+                        glyphOffset += sideIncrement;
+                        positionIncrement = glyphOffset;
+                        glyphOffset += sideIncrement;
+                    }
+
+                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
+                    glyphPos.setLocation(glyphPos.getX() + positionIncrement, glyphPos.getY());
+                    getGlyphVector().setGlyphPosition(i, glyphPos);
+                }
+            } else {
+                for (int i=firstGlyph; i<=lastGlyph; i++) {
+                    GlyphJustificationInfo gji = getGlyphJustificationInfos()[i];
+                    currInfo = jInfos[gji.shrinkPriority];
+                    if (currInfo == null) {
+                        // We still have to increment glyph position
+                        Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
+                        glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
+                        getGlyphVector().setGlyphPosition(i, glyphPos);
+
+                        continue;
+                    }
+
+                    if (currInfo.useLimits) {
+                        glyphOffset -= gji.shrinkLeftLimit;
+                        if (currInfo.absorb) {
+                            sideIncrement = gji.weight * currInfo.absorbedGapPerUnit;
+                            glyphOffset += sideIncrement;
+                            positionIncrement = glyphOffset;
+                            glyphOffset += sideIncrement;
+                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
+                            sideIncrement = gji.weight * lastInfo.absorbedGapPerUnit;
+                            glyphOffset += sideIncrement;
+                            positionIncrement = glyphOffset;
+                            glyphOffset += sideIncrement;
+                        } else {
+                            positionIncrement = glyphOffset;
+                        }
+                        glyphOffset -= gji.shrinkRightLimit;
+                    } else {
+                        sideIncrement =  gji.weight * currInfo.gapPerUnit;
+                        glyphOffset += sideIncrement;
+                        positionIncrement = glyphOffset;
+                        glyphOffset += sideIncrement;
+                    }
+
+                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
+                    glyphPos.setLocation(glyphPos.getX() + positionIncrement, glyphPos.getY());
+                    getGlyphVector().setGlyphPosition(i, glyphPos);
+                }
+            }
+
+
+            if (haveLast) {   // Don't add padding after last char
+                lastGlyph++;
+
+                GlyphJustificationInfo gji = getGlyphJustificationInfos()[lastGlyph];
+                currInfo = jInfos[gji.growPriority];
+
+                if (currInfo != null) {
+                    if (currInfo.useLimits) {
+                        glyphOffset += firstInfo.grow ? gji.growLeftLimit : -gji.shrinkLeftLimit;
+                        if (currInfo.absorb) {
+                            glyphOffset += gji.weight * currInfo.absorbedGapPerUnit;
+                        } else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
+                            glyphOffset += gji.weight * lastInfo.absorbedGapPerUnit;
+                        }
+                    } else {
+                        glyphOffset += gji.weight * currInfo.gapPerUnit;
+                    }
+                }
+
+                // Ajust positions of all glyphs after last glyph
+                for (int i=lastGlyph; i<getGlyphVector().getNumGlyphs()+1; i++) {
+                    Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
+                    glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
+                    getGlyphVector().setGlyphPosition(i, glyphPos);
+                }
+            } else { // Update position after last glyph in glyph vector -
+                // to get correct advance for it
+                Point2D glyphPos = getGlyphVector().getGlyphPosition(lastGlyph+1);
+                glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
+                getGlyphVector().setGlyphPosition(lastGlyph+1, glyphPos);
+            }
+
+            gjis = null; // We don't need justification infos any more
+            // Also we have to reset cached bounds and metrics
+            this.visualBounds = null;
+            this.logicalBounds = null;
+
+            return glyphOffset; // How much our segment grown or shrunk
+        }
+    }
+
+    public static class TextRunSegmentGraphic extends TextRunSegment {
+        GraphicAttribute ga;
+        int start;
+        int length;
+        float fullAdvance;
+
+        TextRunSegmentGraphic(GraphicAttribute attr, int len, int start) {
+            this.start = start;
+            length = len;
+            ga = attr;
+            metrics = new BasicMetrics(ga);
+            fullAdvance = ga.getAdvance() * length;
+        }
+
+        @Override
+        public Object clone() {
+            return new TextRunSegmentGraphic(ga, length, start);
+        }
+
+        // Renders this text run segment
+        @Override
+        void draw(Graphics2D g2d, float xOffset, float yOffset) {
+            if (decoration != null) {
+                TextDecorator.prepareGraphics(this, g2d, xOffset, yOffset);
+            }
+
+            float xPos = x + xOffset;
+            float yPos = y + yOffset;
+
+            for (int i=0; i < length; i++) {
+                ga.draw(g2d, xPos, yPos);
+                xPos += ga.getAdvance();
+            }
+
+            if (decoration != null) {
+                TextDecorator.drawTextDecorations(this, g2d, xOffset, yOffset);
+                TextDecorator.restoreGraphics(decoration, g2d);
+            }
+        }
+
+        // Returns visual bounds of this segment
+        @Override
+        Rectangle2D getVisualBounds() {
+            if (visualBounds == null) {
+                Rectangle2D bounds = ga.getBounds();
+
+                // First and last chars can be out of logical bounds, so we calculate
+                // (bounds.getWidth() - ga.getAdvance()) which is exactly the difference
+                bounds.setRect(
+                        bounds.getMinX() + x,
+                        bounds.getMinY() + y,
+                        bounds.getWidth() - ga.getAdvance() + getAdvance(),
+                        bounds.getHeight()
+                );
+                visualBounds = TextDecorator.extendVisualBounds(this, bounds, decoration);
+            }
+
+            return (Rectangle2D) visualBounds.clone();
+        }
+
+        @Override
+        Rectangle2D getLogicalBounds() {
+            if (logicalBounds == null) {
+                logicalBounds =
+                        new Rectangle2D.Float(
+                                x, y - metrics.ascent,
+                                getAdvance(), metrics.ascent + metrics.descent
+                        );
+            }
+
+            return (Rectangle2D) logicalBounds.clone();
+        }
+
+        @Override
+        float getAdvance() {
+            return fullAdvance;
+        }
+
+        @Override
+        float getAdvanceDelta(int start, int end) {
+            return ga.getAdvance() * (end - start);
+        }
+
+        @Override
+        int getCharIndexFromAdvance(float advance, int start) {
+            start -= this.start;
+
+            if (start < 0) {
+                start = 0;
+            }
+
+            int charOffset = (int) (advance/ga.getAdvance());
+
+            if (charOffset + start > length) {
+                return length + this.start;
+            }
+            return charOffset + start + this.start;
+        }
+
+        @Override
+        int getStart() {
+            return start;
+        }
+
+        @Override
+        int getEnd() {
+            return start + length;
+        }
+
+        @Override
+        int getLength() {
+            return length;
+        }
+
+        @Override
+        Shape getCharsBlackBoxBounds(int start, int limit) {
+            start -= this.start;
+            limit -= this.start;
+
+            if (limit > length) {
+                limit = length;
+            }
+
+            Rectangle2D charBounds = ga.getBounds();
+            charBounds.setRect(
+                    charBounds.getX() + ga.getAdvance() * start + x,
+                    charBounds.getY() + y,
+                    charBounds.getWidth() + ga.getAdvance() * (limit - start),
+                    charBounds.getHeight()
+            );
+
+            return charBounds;
+        }
+
+        @Override
+        float getCharPosition(int index) {
+            index -= start;
+            if (index > length) {
+                index = length;
+            }
+
+            return ga.getAdvance() * index + x;
+        }
+
+        @Override
+        float getCharAdvance(int index) {
+            return ga.getAdvance();
+        }
+
+        @Override
+        Shape getOutline() {
+            AffineTransform t = AffineTransform.getTranslateInstance(x, y);
+            return t.createTransformedShape(
+                    TextDecorator.extendOutline(this, getVisualBounds(), decoration)
+            );
+        }
+
+        @Override
+        boolean charHasZeroAdvance(int index) {
+            return false;
+        }
+
+        @Override
+        TextHitInfo hitTest(float hitX, float hitY) {
+            hitX -= x;
+
+            float tmp = hitX / ga.getAdvance();
+            int hitIndex = Math.round(tmp);
+
+            if (tmp > hitIndex) {
+                return TextHitInfo.leading(hitIndex + this.start);
+            }
+            return TextHitInfo.trailing(hitIndex + this.start);
+        }
+
+        @Override
+        void updateJustificationInfo(TextRunBreaker.JustificationInfo jInfo) {
+            // Do nothing
+        }
+
+        @Override
+        float doJustification(TextRunBreaker.JustificationInfo jInfos[]) {
+            // Do nothing
+            return 0;
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/BufferedImageGraphics2D.java b/awt/org/apache/harmony/awt/gl/image/BufferedImageGraphics2D.java
new file mode 100644
index 0000000..f1d64fb
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/BufferedImageGraphics2D.java
@@ -0,0 +1,79 @@
+/*
+ *  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 Alexey A. Petrenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.WritableRaster;
+
+import org.apache.harmony.awt.gl.CommonGraphics2D;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.render.JavaBlitter;
+import org.apache.harmony.awt.gl.render.NativeImageBlitter;
+
+/**
+ * BufferedImageGraphics2D is implementation of CommonGraphics2D for
+ * drawing on buffered images. 
+ */
+public class BufferedImageGraphics2D extends CommonGraphics2D {
+    private BufferedImage bi = null;
+    private Rectangle bounds = null;
+
+    public BufferedImageGraphics2D(BufferedImage bi) {
+        super();
+        this.bi = bi;
+        this.bounds = new Rectangle(0, 0, bi.getWidth(), bi.getHeight());
+        clip(bounds);
+        dstSurf = Surface.getImageSurface(bi);
+        if(dstSurf.isNativeDrawable()){
+            blitter = NativeImageBlitter.getInstance();
+        }else{
+            blitter = JavaBlitter.getInstance();
+        }
+    }
+
+    @Override
+    public void copyArea(int x, int y, int width, int height, int dx, int dy) {
+    }
+
+    @Override
+    public Graphics create() {
+        BufferedImageGraphics2D res = new BufferedImageGraphics2D(bi);
+        copyInternalFields(res);
+        return res;
+    }
+
+    @Override
+    public GraphicsConfiguration getDeviceConfiguration() {
+        return null;
+    }
+
+    public ColorModel getColorModel() {
+        return bi.getColorModel();
+    }
+
+    public WritableRaster getWritableRaster() {
+        return bi.getRaster();
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/BufferedImageSource.java b/awt/org/apache/harmony/awt/gl/image/BufferedImageSource.java
new file mode 100644
index 0000000..0fe25a2
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/BufferedImageSource.java
@@ -0,0 +1,136 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.awt.image.IndexColorModel;
+import java.awt.image.WritableRaster;
+import java.util.Hashtable;
+
+public class BufferedImageSource implements ImageProducer {
+
+    private Hashtable<?, ?> properties;
+    private ColorModel cm;
+    private WritableRaster raster;
+    private int width;
+    private int height;
+
+    private ImageConsumer ic;
+
+    public BufferedImageSource(BufferedImage image, Hashtable<?, ?> properties){
+        if(properties == null) {
+            this.properties = new Hashtable<Object, Object>();
+        } else {
+            this.properties = properties;
+        }
+
+        width = image.getWidth();
+        height = image.getHeight();
+        cm = image.getColorModel();
+        raster = image.getRaster();
+    }
+
+    public BufferedImageSource(BufferedImage image){
+        this(image, null);
+    }
+
+    public boolean isConsumer(ImageConsumer ic) {
+        return (this.ic == ic);
+    }
+
+    public void startProduction(ImageConsumer ic) {
+        addConsumer(ic);
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer ic) {
+    }
+
+    public void removeConsumer(ImageConsumer ic) {
+        if (this.ic == ic) {
+            this.ic = null;
+        }
+    }
+
+    public void addConsumer(ImageConsumer ic) {
+        this.ic = ic;
+        startProduction();
+    }
+
+    private void startProduction(){
+        try {
+            ic.setDimensions(width, height);
+            ic.setProperties(properties);
+            ic.setColorModel(cm);
+            ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
+                    ImageConsumer.COMPLETESCANLINES |
+                    ImageConsumer.SINGLEFRAME |
+                    ImageConsumer.SINGLEPASS);
+            if(cm instanceof IndexColorModel &&
+                    raster.getTransferType() == DataBuffer.TYPE_BYTE ||
+                    cm instanceof ComponentColorModel &&
+                    raster.getTransferType() == DataBuffer.TYPE_BYTE &&
+                    raster.getNumDataElements() == 1){
+                DataBufferByte dbb = (DataBufferByte) raster.getDataBuffer();
+                byte data[] = dbb.getData();
+                int off = dbb.getOffset();
+                ic.setPixels(0, 0, width, height, cm, data, off, width);
+            }else if(cm instanceof DirectColorModel &&
+                    raster.getTransferType() == DataBuffer.TYPE_INT){
+                DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
+                int data[] = dbi.getData();
+                int off = dbi.getOffset();
+                ic.setPixels(0, 0, width, height, cm, data, off, width);
+            }else if(cm instanceof DirectColorModel &&
+                    raster.getTransferType() == DataBuffer.TYPE_BYTE){
+                DataBufferByte dbb = (DataBufferByte) raster.getDataBuffer();
+                byte data[] = dbb.getData();
+                int off = dbb.getOffset();
+                ic.setPixels(0, 0, width, height, cm, data, off, width);
+            }else{
+                ColorModel rgbCM = ColorModel.getRGBdefault();
+                int pixels[] = new int[width];
+                Object pix = null;
+                for(int y = 0; y < height; y++){
+                    for(int x = 0 ; x < width; x++){
+                        pix = raster.getDataElements(x, y, pix);
+                        pixels[x] = cm.getRGB(pix);
+                    }
+                    ic.setPixels(0, y, width, 1, rgbCM, pixels, 0, width);
+                }
+            }
+            ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
+        }catch (NullPointerException e){
+            if (ic != null) {
+                ic.imageComplete(ImageConsumer.IMAGEERROR);
+            }
+        }
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/ByteArrayDecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/ByteArrayDecodingImageSource.java
new file mode 100644
index 0000000..cc6d7cf
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/ByteArrayDecodingImageSource.java
@@ -0,0 +1,62 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+/*
+ * Created on 10.02.2005
+ *
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+public class ByteArrayDecodingImageSource extends DecodingImageSource {
+
+    byte imagedata[];
+    int imageoffset;
+    int imagelength;
+
+    public ByteArrayDecodingImageSource(byte imagedata[], int imageoffset,
+            int imagelength){
+        this.imagedata = imagedata;
+        this.imageoffset = imageoffset;
+        this.imagelength = imagelength;
+    }
+
+    public ByteArrayDecodingImageSource(byte imagedata[]){
+        this(imagedata, 0, imagedata.length);
+    }
+
+    @Override
+    protected boolean checkConnection() {
+        return true;
+    }
+
+    @Override
+    protected InputStream getInputStream() {
+        // BEGIN android-modified
+        // TODO: Why does a ByteArrayInputStream need to be buffered at all?
+        return new BufferedInputStream(new ByteArrayInputStream(imagedata,
+                        imageoffset, imagelength), 1024);
+        // END android-modified
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/DataBufferListener.java b/awt/org/apache/harmony/awt/gl/image/DataBufferListener.java
new file mode 100644
index 0000000..8793050
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/DataBufferListener.java
@@ -0,0 +1,31 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 13.03.2006
+ *
+ */
+package org.apache.harmony.awt.gl.image;
+
+public interface DataBufferListener {
+    
+    void dataChanged();
+    void dataTaken();
+    void dataReleased();
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/DecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/DecodingImageSource.java
new file mode 100644
index 0000000..958d691
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/DecodingImageSource.java
@@ -0,0 +1,261 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+/*
+ * Created on 18.01.2005
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This is an abstract class that encapsulates a main part of ImageProducer functionality
+ * for the images being decoded by the native decoders, like PNG, JPEG and GIF.
+ * It helps to integrate image decoders into producer/consumer model. It provides
+ * functionality for working with several decoder instances and several image consumers
+ * simultaneously.
+ */
+public abstract class DecodingImageSource implements ImageProducer {
+    List<ImageConsumer> consumers = new ArrayList<ImageConsumer>(5);
+    List<ImageDecoder> decoders = new ArrayList<ImageDecoder>(5);
+    boolean loading;
+
+    ImageDecoder decoder;
+
+    protected abstract boolean checkConnection();
+
+    protected abstract InputStream getInputStream();
+
+    public synchronized void addConsumer(ImageConsumer ic) {
+        if (!checkConnection()) { // No permission for this consumer
+            ic.imageComplete(ImageConsumer.IMAGEERROR);
+            return;
+        }
+
+        ImageConsumer cons = findConsumer(consumers, ic);
+
+        if (cons == null) { // Try to look in the decoders
+            ImageDecoder d = null;
+
+            // Check for all existing decoders
+            for (Iterator<ImageDecoder> i = decoders.iterator(); i.hasNext();) {
+                d = i.next();
+                cons = findConsumer(d.consumers, ic);
+                if (cons != null) {
+                    break;
+                }
+            }
+        }
+
+        if (cons == null) { // Not found, add this consumer
+            consumers.add(ic);
+        }
+    }
+
+    /**
+     * This method stops sending data to the given consumer
+     * @param ic - consumer
+     */
+    private void abortConsumer(ImageConsumer ic) {
+        ic.imageComplete(ImageConsumer.IMAGEERROR);
+        consumers.remove(ic);
+    }
+
+    /**
+     * This method stops sending data to the list of consumers.
+     * @param consumersList - list of consumers
+     */
+    private void abortAllConsumers(List<ImageConsumer> consumersList) {
+        for (ImageConsumer imageConsumer : consumersList) {
+            abortConsumer(imageConsumer);
+        }
+    }
+
+    public synchronized void removeConsumer(ImageConsumer ic) {
+        ImageDecoder d = null;
+
+        // Remove in all existing decoders
+        for (Iterator<ImageDecoder> i = decoders.iterator(); i.hasNext();) {
+            d = i.next();
+            removeConsumer(d.consumers, ic);
+            if (d.consumers.size() <= 0) {
+                d.terminate();
+            }
+        }
+
+        // Remove in the current queue of consumers
+        removeConsumer(consumers, ic);
+    }
+
+    /**
+     * Static implementation of removeConsumer method
+     * @param consumersList - list of consumers
+     * @param ic - consumer to be removed
+     */
+    private static void removeConsumer(List<ImageConsumer> consumersList, ImageConsumer ic) {
+        ImageConsumer cons = null;
+
+        for (Iterator<ImageConsumer> i = consumersList.iterator(); i.hasNext();) {
+            cons = i.next();
+            if (cons.equals(ic)) {
+                i.remove();
+            }
+        }
+    }
+
+    public void requestTopDownLeftRightResend(ImageConsumer consumer) {
+        // Do nothing
+    }
+
+    public synchronized void startProduction(ImageConsumer ic) {
+        if (ic != null) {
+            addConsumer(ic);
+        }
+
+        if (!loading && consumers.size() > 0) {
+            ImageLoader.addImageSource(this);
+            loading = true;
+        }
+    }
+
+    public synchronized boolean isConsumer(ImageConsumer ic) {
+        ImageDecoder d = null;
+
+        // Check for all existing decoders
+        for (Iterator<ImageDecoder> i = decoders.iterator(); i.hasNext();) {
+            d = i.next();
+            if (findConsumer(d.consumers, ic) != null) {
+                return true;
+            }
+        }
+
+        // Check current queue of consumers
+        return findConsumer(consumers, ic) != null;
+    }
+
+    /**
+     * Checks if the consumer is in the list and returns it it is there
+     * @param consumersList - list of consumers
+     * @param ic - consumer
+     * @return consumer if found, null otherwise
+     */
+    private static ImageConsumer findConsumer(List<ImageConsumer> consumersList, ImageConsumer ic) {
+        ImageConsumer res = null;
+
+        for (Iterator<ImageConsumer> i = consumersList.iterator(); i.hasNext();) {
+            res = i.next();
+            if (res.equals(ic)) {
+                return res;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Use this method to finish decoding or lock the list of consumers
+     * for a particular decoder
+     * @param d - decoder
+     */
+    synchronized void lockDecoder(ImageDecoder d) {
+        if (d == decoder) {
+            decoder = null;
+            startProduction(null);
+        }
+    }
+
+    /**
+     * Tries to find an appropriate decoder for the input stream and adds it
+     * to the list of decoders
+     * @return created decoder
+     */
+    private ImageDecoder createDecoder() {
+        InputStream is = getInputStream();
+
+        ImageDecoder decoder;
+
+        if (is == null) {
+            decoder = null;
+        } else {
+            decoder = ImageDecoder.createDecoder(this, is);
+        }
+
+        if (decoder != null) {
+            synchronized (this) {
+                decoders.add(decoder);
+                this.decoder = decoder;
+                loading = false;
+                consumers = new ArrayList<ImageConsumer>(5); // Reset queue
+            }
+
+            return decoder;
+        }
+        // We were not able to find appropriate decoder
+        List<ImageConsumer> cs;
+        synchronized (this) {
+            cs = consumers;
+            consumers = new ArrayList<ImageConsumer>(5);
+            loading = false;
+        }
+        abortAllConsumers(cs);
+
+        return null;
+    }
+
+    /**
+     * Stop the given decoder and remove it from the list
+     * @param dr - decoder
+     */
+    private synchronized void removeDecoder(ImageDecoder dr) {
+        lockDecoder(dr);
+        decoders.remove(dr);
+    }
+
+    /**
+     * This method serves as an entry point.
+     * It starts the decoder and loads the image data.
+     */
+    public void load() {
+        synchronized (this) {
+            if (consumers.size() == 0) {
+                loading = false;
+                return;
+            }
+        }
+
+        ImageDecoder d = createDecoder();
+        if (d != null) {
+            try {
+                decoder.decodeImage();
+            } catch (IOException e) {
+                e.printStackTrace();
+            } finally {
+                removeDecoder(d);
+                abortAllConsumers(d.consumers);
+            }
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/FileDecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/FileDecodingImageSource.java
new file mode 100644
index 0000000..54d4664
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/FileDecodingImageSource.java
@@ -0,0 +1,68 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+/*
+ * Created on 20.01.2005
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+public class FileDecodingImageSource extends DecodingImageSource {
+  String filename;
+
+  public FileDecodingImageSource(String file) {
+    SecurityManager security = System.getSecurityManager();
+    if (security != null) {
+        security.checkRead(file);
+    }
+
+    filename = file;
+  }
+
+  @Override
+protected boolean checkConnection() {
+      SecurityManager security = System.getSecurityManager();
+      if (security != null) {
+          try {
+            security.checkRead(filename);
+          } catch (SecurityException e) {
+              return false;
+          }
+      }
+
+      return true;
+  }
+
+  @Override
+protected InputStream getInputStream() {
+    try {
+      // BEGIN android-modified
+      return new BufferedInputStream(new FileInputStream(filename), 8192);
+      // END android-modified
+    } catch (FileNotFoundException e) {
+      return null;
+    }
+  }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/GifDecoder.java b/awt/org/apache/harmony/awt/gl/image/GifDecoder.java
new file mode 100644
index 0000000..7ecb15b
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/GifDecoder.java
@@ -0,0 +1,692 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+/*
+* Created on 27.01.2005
+*/
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.image.ColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.IndexColorModel;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+
+public class GifDecoder extends ImageDecoder {
+    // initializes proper field IDs
+    private static native void initIDs();
+
+    static {
+        System.loadLibrary("gl"); //$NON-NLS-1$
+        initIDs();
+    }
+
+    // ImageConsumer hints: common
+    private static final int baseHints =
+            ImageConsumer.SINGLEPASS | ImageConsumer.COMPLETESCANLINES |
+            ImageConsumer.SINGLEFRAME;
+    // ImageConsumer hints: interlaced
+    private static final int interlacedHints =
+            baseHints | ImageConsumer.RANDOMPIXELORDER;
+
+    // Impossible color value - no translucent pixels allowed
+    static final int IMPOSSIBLE_VALUE = 0x0FFFFFFF;
+
+    // I/O buffer
+    private static final int BUFFER_SIZE = 1024;
+    private byte buffer[] = new byte[BUFFER_SIZE];
+
+    GifDataStream gifDataStream = new GifDataStream();
+    GifGraphicBlock currBlock;
+
+    // Pointer to native structure which store decoding state
+    // between subsequent decoding/IO-suspension cycles
+    private long hNativeDecoder; // NULL initially
+
+    // Number of bytes eaten by the native decoder
+    private int bytesConsumed;
+
+    private boolean consumersPrepared;
+    private Hashtable<String, String> properties = new Hashtable<String, String>();
+
+    // Could be set up by java code or native method when
+    // transparent pixel index changes or local color table encountered
+    private boolean forceRGB;
+
+    private byte screenBuffer[];
+    private int screenRGBBuffer[];
+
+    public GifDecoder(DecodingImageSource src, InputStream is) {
+        super(src, is);
+    }
+
+    private static native int[] toRGB(byte imageData[], byte colormap[], int transparentColor);
+
+    private static native void releaseNativeDecoder(long hDecoder);
+
+    private native int decode(
+            byte input[],
+            int bytesInBuffer,
+            long hDecoder,
+            GifDataStream dataStream,
+            GifGraphicBlock currBlock
+            );
+
+    private int[] getScreenRGBBuffer() {
+        if (screenRGBBuffer == null) {
+            if (screenBuffer != null) {
+                int transparentColor =
+                        gifDataStream.logicalScreen.globalColorTable.cm.getTransparentPixel();
+                transparentColor = transparentColor > 0 ? transparentColor : IMPOSSIBLE_VALUE;
+                screenRGBBuffer =
+                        toRGB(
+                                screenBuffer,
+                                gifDataStream.logicalScreen.globalColorTable.colors,
+                                transparentColor
+                        );
+            } else {
+                int size = gifDataStream.logicalScreen.logicalScreenHeight *
+                        gifDataStream.logicalScreen.logicalScreenWidth;
+                screenRGBBuffer = new int[size];
+            }
+        }
+
+        return screenRGBBuffer;
+    }
+
+    private void prepareConsumers() {
+        GifLogicalScreen gls = gifDataStream.logicalScreen;
+        setDimensions(gls.logicalScreenWidth,
+                gls.logicalScreenHeight);
+        setProperties(properties);
+
+        currBlock = gifDataStream.graphicBlocks.get(0);
+        if (forceRGB) {
+            setColorModel(ColorModel.getRGBdefault());
+        } else {
+            setColorModel(gls.globalColorTable.getColorModel(currBlock.transparentColor));
+        }
+
+        // Fill screen buffer with the background or transparent color
+        if (forceRGB) {
+            int fillColor = 0xFF000000;
+            if (gls.backgroundColor != IMPOSSIBLE_VALUE) {
+                fillColor = gls.backgroundColor;
+            }
+
+            Arrays.fill(getScreenRGBBuffer(), fillColor);
+        } else {
+            int fillColor = 0;
+
+            if (gls.backgroundColor != IMPOSSIBLE_VALUE) {
+                fillColor = gls.backgroundColor;
+            } else {
+                fillColor = gls.globalColorTable.cm.getTransparentPixel();
+            }
+
+            screenBuffer = new byte[gls.logicalScreenHeight*gls.logicalScreenWidth];
+            Arrays.fill(screenBuffer, (byte) fillColor);
+        }
+
+        setHints(interlacedHints); // XXX - always random pixel order
+    }
+
+    @Override
+    public void decodeImage() throws IOException {
+        try {
+            int bytesRead = 0;
+            int needBytes, offset, bytesInBuffer = 0;
+            boolean eosReached = false;
+            GifGraphicBlock blockToDispose = null;
+
+            // Create new graphic block
+            if (currBlock == null) {
+                currBlock = new GifGraphicBlock();
+                gifDataStream.graphicBlocks.add(currBlock);
+            }
+
+            // Read from the input stream
+            for (;;) {
+                needBytes = BUFFER_SIZE - bytesInBuffer;
+                offset = bytesInBuffer;
+
+                bytesRead = inputStream.read(buffer, offset, needBytes);
+
+                if (bytesRead < 0) {
+                    eosReached = true;
+                    bytesRead = 0;
+                } // Don't break, maybe something left in buffer
+
+                // Keep track on how much bytes left in buffer
+                bytesInBuffer += bytesRead;
+
+                // Here we pass number of new bytes read from the input stream (bytesRead)
+                // since native decoder uses java buffer and doesn't have its own
+                // buffer. So it adds this number to the number of bytes left
+                // in buffer from the previous call.
+                int numLines = decode(
+                        buffer,
+                        bytesRead,
+                        hNativeDecoder,
+                        gifDataStream,
+                        currBlock);
+
+                // Keep track on how much bytes left in buffer
+                bytesInBuffer -= bytesConsumed;
+
+                if (
+                        !consumersPrepared &&
+                        gifDataStream.logicalScreen.completed &&
+                        gifDataStream.logicalScreen.globalColorTable.completed &&
+                        (currBlock.imageData != null || // Have transparent pixel filled
+                        currBlock.rgbImageData != null)
+                ) {
+                    prepareConsumers();
+                    consumersPrepared = true;
+                }
+
+                if (bytesConsumed < 0) {
+                    break; // Error exit
+                }
+
+                if (currBlock != null) {
+                    if (numLines != 0) {
+                        // Dispose previous image only before showing next
+                        if (blockToDispose != null) {
+                            blockToDispose.dispose();
+                            blockToDispose = null;
+                        }
+
+                        currBlock.sendNewData(this, numLines);
+                    }
+
+                    if (currBlock.completed && hNativeDecoder != 0) {
+                        blockToDispose = currBlock; // Dispose only before showing new pixels
+                        currBlock = new GifGraphicBlock();
+                        gifDataStream.graphicBlocks.add(currBlock);
+                    }
+                }
+
+                if (hNativeDecoder == 0) {
+                    break;
+                }
+
+                if (eosReached && numLines == 0) { // Maybe image is truncated...
+                    releaseNativeDecoder(hNativeDecoder);
+                    break;
+                }
+            }
+        } finally {
+            closeStream();
+        }
+
+        // Here all animation goes
+        // Repeat image loopCount-1 times or infinitely if loopCount = 0
+        if (gifDataStream.loopCount != 1) {
+            if (currBlock.completed == false) {
+                gifDataStream.graphicBlocks.remove(currBlock);
+            }
+
+            int numFrames = gifDataStream.graphicBlocks.size();
+            // At first last block will be disposed
+            GifGraphicBlock gb =
+                    gifDataStream.graphicBlocks.get(numFrames-1);
+
+            ImageLoader.beginAnimation();
+
+            while (gifDataStream.loopCount != 1) {
+                if (gifDataStream.loopCount != 0) {
+                    gifDataStream.loopCount--;
+                }
+
+                // Show all frames
+                for (int i=0; i<numFrames; i++) {
+                    gb.dispose();
+                    gb = gifDataStream.graphicBlocks.get(i);
+
+                    // Show one frame
+                    if (forceRGB) {
+                        setPixels(
+                                gb.imageLeft,
+                                gb.imageTop,
+                                gb.imageWidth,
+                                gb.imageHeight,
+                                ColorModel.getRGBdefault(),
+                                gb.getRgbImageData(),
+                                0,
+                                gb.imageWidth
+                        );
+                    } else {
+                        setPixels(
+                                gb.imageLeft,
+                                gb.imageTop,
+                                gb.imageWidth,
+                                gb.imageHeight,
+                                null,
+                                gb.imageData,
+                                0,
+                                gb.imageWidth
+                        );
+                    }
+                }
+            }
+            ImageLoader.endAnimation();
+        }
+
+        imageComplete(ImageConsumer.STATICIMAGEDONE);
+    }
+
+    void setComment(String newComment) {
+        Object currComment = properties.get("comment"); //$NON-NLS-1$
+
+        if (currComment == null) {
+            properties.put("comment", newComment); //$NON-NLS-1$
+        } else {
+            properties.put("comment", (String) currComment + "\n" + newComment); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        setProperties(properties);
+    }
+
+    class GifDataStream {
+        //  Indicates that reading of the whole data stream accomplished
+        boolean completed = false;
+
+        // Added to support Netscape 2.0 application
+        // extension block.
+        int loopCount = 1;
+
+        GifLogicalScreen logicalScreen = new GifLogicalScreen();
+        List<GifGraphicBlock> graphicBlocks = new ArrayList<GifGraphicBlock>(10); // Of GifGraphicBlocks
+
+        // Comments from the image
+        String comments[];
+    }
+
+    class GifLogicalScreen {
+        //  Indicates that reading of this block accomplished
+        boolean completed = false;
+
+        int logicalScreenWidth;
+        int logicalScreenHeight;
+
+        int backgroundColor = IMPOSSIBLE_VALUE;
+
+        GifColorTable globalColorTable = new GifColorTable();
+    }
+
+    class GifGraphicBlock {
+        //  Indicates that reading of this block accomplished
+        boolean completed = false;
+
+        final static int DISPOSAL_NONE = 0;
+        final static int DISPOSAL_NODISPOSAL = 1;
+        final static int DISPOSAL_BACKGROUND = 2;
+        final static int DISPOSAL_RESTORE = 3;
+
+        int disposalMethod;
+        int delayTime; // Multiplied by 10 already
+        int transparentColor = IMPOSSIBLE_VALUE;
+
+        int imageLeft;
+        int imageTop;
+        int imageWidth;
+        int imageHeight;
+
+        // Auxilliary variables to minimize computations
+        int imageRight;
+        int imageBottom;
+
+        boolean interlace;
+
+        // Don't need local color table - if it is specified
+        // image data are converted to RGB in the native code
+
+        byte imageData[] = null;
+        int rgbImageData[] = null;
+
+        private int currY = 0; // Current output scanline
+
+        int[] getRgbImageData() {
+            if (rgbImageData == null) {
+                rgbImageData =
+                        toRGB(
+                                imageData,
+                                gifDataStream.logicalScreen.globalColorTable.colors,
+                                transparentColor
+                        );
+                if (transparentColor != IMPOSSIBLE_VALUE) {
+                    transparentColor =
+                            gifDataStream.logicalScreen.globalColorTable.cm.getRGB(transparentColor);
+                    transparentColor &= 0x00FFFFFF;
+                }
+            }
+            return rgbImageData;
+        }
+
+        private void replaceTransparentPixels(int numLines) {
+            List<GifGraphicBlock> graphicBlocks = gifDataStream.graphicBlocks;
+            int prevBlockIndex = graphicBlocks.indexOf(this) - 1;
+
+            if (prevBlockIndex >= 0) {
+                int maxY = currY + numLines + imageTop;
+                int offset = currY * imageWidth;
+
+                // Update right and bottom coordinates
+                imageRight = imageLeft + imageWidth;
+                imageBottom = imageTop + imageHeight;
+
+                int globalWidth = gifDataStream.logicalScreen.logicalScreenWidth;
+                int pixelValue, imageOffset;
+                int rgbData[] = forceRGB ? getRgbImageData() : null;
+
+                for (int y = currY + imageTop; y < maxY; y++) {
+                    imageOffset = globalWidth * y + imageLeft;
+                    for (int x = imageLeft; x < imageRight; x++) {
+                        pixelValue = forceRGB ?
+                                rgbData[offset] :
+                                imageData[offset] & 0xFF;
+                        if (pixelValue == transparentColor) {
+                            if (forceRGB) {
+                                pixelValue = getScreenRGBBuffer() [imageOffset];
+                                rgbData[offset] = pixelValue;
+                            } else {
+                                pixelValue = screenBuffer [imageOffset];
+                                imageData[offset] = (byte) pixelValue;
+                            }
+                        }
+                        offset++;
+                        imageOffset++;
+                    } // for
+                } // for
+
+            } // if (prevBlockIndex >= 0)
+        }
+
+        public void sendNewData(GifDecoder decoder, int numLines) {
+            // Get values for transparent pixels
+            // from the perevious frames
+            if (transparentColor != IMPOSSIBLE_VALUE) {
+                replaceTransparentPixels(numLines);
+            }
+
+            if (forceRGB) {
+                decoder.setPixels(
+                        imageLeft,
+                        imageTop + currY,
+                        imageWidth,
+                        numLines,
+                        ColorModel.getRGBdefault(),
+                        getRgbImageData(),
+                        currY*imageWidth,
+                        imageWidth
+                );
+            } else {
+                decoder.setPixels(
+                        imageLeft,
+                        imageTop + currY,
+                        imageWidth,
+                        numLines,
+                        null,
+                        imageData,
+                        currY*imageWidth,
+                        imageWidth
+                );
+            }
+
+            currY += numLines;
+        }
+
+        public void dispose() {
+            imageComplete(ImageConsumer.SINGLEFRAMEDONE);
+
+            // Show current frame until delayInterval will not elapse
+            if (delayTime > 0) {
+                try {
+                    Thread.sleep(delayTime);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            } else {
+                Thread.yield(); // Allow consumers to consume data
+            }
+
+            // Don't dispose if image is outside of the visible area
+            if (imageLeft > gifDataStream.logicalScreen.logicalScreenWidth ||
+                    imageTop > gifDataStream.logicalScreen.logicalScreenHeight) {
+                disposalMethod = DISPOSAL_NONE;
+            }
+
+            switch(disposalMethod) {
+                case DISPOSAL_BACKGROUND: {
+                    if (forceRGB) {
+                        getRgbImageData(); // Ensure that transparentColor is RGB, not index
+
+                        int data[] = new int[imageWidth*imageHeight];
+
+                        // Compatibility: Fill with transparent color if we have one
+                        if (transparentColor != IMPOSSIBLE_VALUE) {
+                            Arrays.fill(
+                                    data,
+                                    transparentColor
+                            );
+                        } else {
+                            Arrays.fill(
+                                    data,
+                                    gifDataStream.logicalScreen.backgroundColor
+                            );
+                        }
+
+                        setPixels(
+                                imageLeft,
+                                imageTop,
+                                imageWidth,
+                                imageHeight,
+                                ColorModel.getRGBdefault(),
+                                data,
+                                0,
+                                imageWidth
+                        );
+
+                        sendToScreenBuffer(data);
+                    } else {
+                        byte data[] = new byte[imageWidth*imageHeight];
+
+                        // Compatibility: Fill with transparent color if we have one
+                        if (transparentColor != IMPOSSIBLE_VALUE) {
+                            Arrays.fill(
+                                    data,
+                                    (byte) transparentColor
+                            );
+                        } else {
+                            Arrays.fill(
+                                    data,
+                                    (byte) gifDataStream.logicalScreen.backgroundColor
+                            );
+                        }
+
+                        setPixels(
+                                imageLeft,
+                                imageTop,
+                                imageWidth,
+                                imageHeight,
+                                null,
+                                data,
+                                0,
+                                imageWidth
+                        );
+
+                        sendToScreenBuffer(data);
+                    }
+                    break;
+                }
+                case DISPOSAL_RESTORE: {
+                    screenBufferToScreen();
+                    break;
+                }
+                case DISPOSAL_NONE:
+                case DISPOSAL_NODISPOSAL:
+                default: {
+                    // Copy transmitted data to the screen buffer
+                    Object data = forceRGB ? (Object) getRgbImageData() : imageData;
+                    sendToScreenBuffer(data);
+                    break;
+                }
+            }
+        }
+
+        private void sendToScreenBuffer(Object data) {
+            int dataInt[];
+            byte dataByte[];
+
+            int width = gifDataStream.logicalScreen.logicalScreenWidth;
+
+
+            if (forceRGB) {
+                dataInt = (int[]) data;
+
+                if (imageWidth == width) {
+                    System.arraycopy(dataInt,
+                            0,
+                            getScreenRGBBuffer(),
+                            imageLeft + imageTop*width,
+                            dataInt.length
+                    );
+                } else { // Each scanline
+                    copyScanlines(dataInt, getScreenRGBBuffer(), width);
+                }
+            } else {
+                dataByte = (byte[]) data;
+
+                if (imageWidth == width) {
+                    System.arraycopy(dataByte,
+                            0,
+                            screenBuffer,
+                            imageLeft + imageTop*width,
+                            dataByte.length
+                    );
+                } else { // Each scanline
+                    copyScanlines(dataByte, screenBuffer, width);
+                }
+            }
+        } // sendToScreenBuffer
+
+        private void copyScanlines(Object src, Object dst, int width) {
+            for (int i=0; i<imageHeight; i++) {
+                System.arraycopy(src,
+                        i*imageWidth,
+                        dst,
+                        imageLeft + i*width + imageTop*width,
+                        imageWidth
+                );
+            } // for
+        }
+
+        private void screenBufferToScreen() {
+            int width = gifDataStream.logicalScreen.logicalScreenWidth;
+
+            Object dst = forceRGB ?
+                    (Object) new int[imageWidth*imageHeight] :
+                    new byte[imageWidth*imageHeight];
+
+            Object src = forceRGB ?
+                    getScreenRGBBuffer() :
+                    (Object) screenBuffer;
+
+            int offset = 0;
+            Object toSend;
+
+            if (width == imageWidth) {
+                offset = imageWidth * imageTop;
+                toSend = src;
+            } else {
+                for (int i=0; i<imageHeight; i++) {
+                    System.arraycopy(src,
+                            imageLeft + i*width + imageTop*width,
+                            dst,
+                            i*imageWidth,
+                            imageWidth
+                    );
+                } // for
+                toSend = dst;
+            }
+
+            if (forceRGB) {
+                setPixels(
+                        imageLeft,
+                        imageTop,
+                        imageWidth,
+                        imageHeight,
+                        ColorModel.getRGBdefault(),
+                        (int [])toSend,
+                        offset,
+                        imageWidth
+                );
+            } else {
+                setPixels(
+                        imageLeft,
+                        imageTop,
+                        imageWidth,
+                        imageHeight,
+                        null,
+                        (byte [])toSend,
+                        offset,
+                        imageWidth
+                );
+            }
+        }
+    }
+
+    class GifColorTable {
+        //  Indicates that reading of this block accomplished
+        boolean completed = false;
+
+        IndexColorModel cm = null;
+        int size = 0; // Actual number of colors in the color table
+        byte colors[] = new byte[256*3];
+
+        IndexColorModel getColorModel(int transparentColor) {
+            if (cm != null) {
+                if (transparentColor != cm.getTransparentPixel()) {
+                    return cm = null; // Force default ARGB color model
+                }
+                return cm;
+            } else
+                if (completed && size > 0) {
+                    if (transparentColor == IMPOSSIBLE_VALUE) {
+                        return cm =
+                                new IndexColorModel(8, size, colors, 0, false);
+                    }
+
+                    if (transparentColor > size) {
+                        size = transparentColor + 1;
+                    }
+                    return cm =
+                            new IndexColorModel(8, size, colors, 0, false, transparentColor);
+                }
+
+            return cm = null; // Force default ARGB color model
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/ImageDecoder.java b/awt/org/apache/harmony/awt/gl/image/ImageDecoder.java
new file mode 100644
index 0000000..d16128e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/ImageDecoder.java
@@ -0,0 +1,258 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+/*
+ * Created on 18.01.2005
+ */
+package org.apache.harmony.awt.gl.image;
+
+import com.android.internal.awt.AndroidImageDecoder;
+
+import java.awt.image.ColorModel;
+import java.awt.image.ImageConsumer;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ConcurrentModificationException;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * This class contains common functionality for all image decoders.
+ */
+public abstract class ImageDecoder {
+    
+    /** Image types */
+    public static final int GENERIC_DECODER = 0;
+    public static final int JPG_DECODER = 1;
+    public static final int GIF_DECODER = 2;
+    public static final int PNG_DECODER = 3;
+    
+    private static final int MAX_BYTES_IN_SIGNATURE = 8;
+
+    protected List<ImageConsumer> consumers;
+    protected InputStream inputStream;
+    protected DecodingImageSource src;
+
+    protected boolean terminated;
+
+    /**
+     * Chooses appropriate image decoder by looking into input stream and checking
+     * the image signature.
+     * @param src - image producer, required for passing data to it from the
+     * created decoder via callbacks
+     * @param is - stream
+     * @return decoder
+     */
+    static ImageDecoder createDecoder(DecodingImageSource src, InputStream is) {
+        InputStream markable;
+
+        if (!is.markSupported()) {
+            // BEGIN android-modified
+            markable = new BufferedInputStream(is, 8192);
+            // END android-modified
+        } else {
+            markable = is;
+        }
+            
+        // Read the signature from the stream and then reset it back
+        try {
+            markable.mark(MAX_BYTES_IN_SIGNATURE);
+
+            byte[] signature = new byte[MAX_BYTES_IN_SIGNATURE];
+            markable.read(signature, 0, MAX_BYTES_IN_SIGNATURE);
+            markable.reset();
+
+            if ((signature[0] & 0xFF) == 0xFF &&
+                    (signature[1] & 0xFF) == 0xD8 &&
+                    (signature[2] & 0xFF) == 0xFF) { // JPEG
+                return loadDecoder(PNG_DECODER, src, is);
+            } else if ((signature[0] & 0xFF) == 0x47 && // G
+                    (signature[1] & 0xFF) == 0x49 && // I
+                    (signature[2] & 0xFF) == 0x46) { // F
+                return loadDecoder(GIF_DECODER, src, is);
+            } else if ((signature[0] & 0xFF) == 137 && // PNG signature: 137 80 78 71 13 10 26 10
+                    (signature[1] & 0xFF) == 80 &&
+                    (signature[2] & 0xFF) == 78 &&
+                    (signature[3] & 0xFF) == 71 &&
+                    (signature[4] & 0xFF) == 13 &&
+                    (signature[5] & 0xFF) == 10 &&
+                    (signature[6] & 0xFF) == 26 &&
+                    (signature[7] & 0xFF) == 10) {
+                return loadDecoder(JPG_DECODER, src, is);
+            }
+
+            return loadDecoder(GENERIC_DECODER, src, is);
+            
+        } catch (IOException e) { // Silently
+        }
+
+        return null;
+    }
+    
+    /*
+     * In the future, we might return different decoders for differen image types.
+     * But for now, we always return the generic one.
+     * Also: we could add a factory to load image decoder.
+     */
+    private static ImageDecoder loadDecoder(int type, DecodingImageSource src, 
+            InputStream is) {
+        return new AndroidImageDecoder(src, is);
+    }
+
+    protected ImageDecoder(DecodingImageSource _src, InputStream is) {
+        src = _src;
+        consumers = src.consumers;
+        inputStream = is;
+    }
+
+    public abstract void decodeImage() throws IOException;
+
+    public synchronized void closeStream() {
+        if (inputStream != null) {
+            try {
+                inputStream.close();
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * Stops the decoding by interrupting the current decoding thread.
+     * Used when all consumers are removed and there's no more need to
+     * run the decoder.
+     */
+    public void terminate() {
+        src.lockDecoder(this);
+        closeStream();
+
+        AccessController.doPrivileged(
+                new PrivilegedAction<Void>() {
+                    public Void run() {
+                        Thread.currentThread().interrupt();
+                        return null;
+                    }
+                }
+        );
+
+        terminated = true;
+    }
+
+    protected void setDimensions(int w, int h) {
+        if (terminated) {
+            return;
+        }
+
+        for (ImageConsumer ic : consumers) {
+            ic.setDimensions(w, h);
+        }
+    }
+
+    protected void setProperties(Hashtable<?, ?> props) {
+        if (terminated) {
+            return;
+        }
+
+        for (ImageConsumer ic : consumers) {
+            ic.setProperties(props);
+        }
+    }
+
+    protected void setColorModel(ColorModel cm) {
+        if (terminated) {
+            return;
+        }
+
+        for (ImageConsumer ic : consumers) {
+            ic.setColorModel(cm);
+        }
+    }
+
+    protected void setHints(int hints) {
+        if (terminated) {
+            return;
+        }
+
+        for (ImageConsumer ic : consumers) {
+            ic.setHints(hints);
+        }
+    }
+
+    protected void setPixels(
+            int x, int y,
+            int w, int h,
+            ColorModel model,
+            byte pix[],
+            int off, int scansize
+            ) {
+        if (terminated) {
+            return;
+        }
+
+        src.lockDecoder(this);
+
+        for (ImageConsumer ic : consumers) {
+            ic.setPixels(x, y, w, h, model, pix, off, scansize);
+        }
+    }
+
+    protected void setPixels(
+            int x, int y,
+            int w, int h,
+            ColorModel model,
+            int pix[],
+            int off, int scansize
+            ) {
+        if (terminated) {
+            return;
+        }
+
+        src.lockDecoder(this);
+
+        for (ImageConsumer ic : consumers) {
+            ic.setPixels(x, y, w, h, model, pix, off, scansize);
+        }
+    }
+
+    protected void imageComplete(int status) {
+        if (terminated) {
+            return;
+        }
+
+        src.lockDecoder(this);
+
+        ImageConsumer ic = null;
+
+        for (Iterator<ImageConsumer> i = consumers.iterator(); i.hasNext();) {
+            try {
+                ic = i.next();
+            } catch (ConcurrentModificationException e) {
+                i = consumers.iterator();
+                continue;
+            }
+            ic.imageComplete(status);
+        }
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/ImageLoader.java b/awt/org/apache/harmony/awt/gl/image/ImageLoader.java
new file mode 100644
index 0000000..5c7d180
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/ImageLoader.java
@@ -0,0 +1,208 @@
+/*
+ *  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+/*
+ * Created on 18.01.2005
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This class provides functionality for simultaneous loading of
+ * several images and running animation.
+ */
+public class ImageLoader extends Thread {
+    // Contains ImageLoader objects
+    // and queue of image sources waiting to be loaded
+    static class ImageLoadersStorage {
+        private static final int MAX_THREADS = 5;
+        private static final int TIMEOUT = 4000;
+        static ImageLoadersStorage instance;
+
+        List<DecodingImageSource> queue = new LinkedList<DecodingImageSource>();
+        List<Thread> loaders = new ArrayList<Thread>(MAX_THREADS);
+
+        private int freeLoaders;
+
+        private ImageLoadersStorage() {}
+
+        static ImageLoadersStorage getStorage() {
+            if (instance == null) {
+                instance = new ImageLoadersStorage();
+            }
+
+            return instance;
+        }
+    }
+
+    ImageLoader() {
+        super();
+        setDaemon(true);
+    }
+
+    /**
+     * This method creates a new thread which is able to load an image
+     * or run animation (if the number of existing loader threads does not
+     * exceed the limit).
+     */
+    private static void createLoader() {
+        final ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+
+        synchronized(storage.loaders) {
+            if (storage.loaders.size() < ImageLoadersStorage.MAX_THREADS) {
+                AccessController.doPrivileged(
+                        new PrivilegedAction<Void>() {
+                            public Void run() {
+                                ImageLoader loader = new ImageLoader();
+                                storage.loaders.add(loader);
+                                loader.start();
+                                return null;
+                            }
+                        });
+            }
+        }
+    }
+
+    /**
+     * Adds a new image source to the queue and starts a new loader
+     * thread if required
+     * @param imgSrc - image source
+     */
+    public static void addImageSource(DecodingImageSource imgSrc) {
+        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+        synchronized(storage.queue) {
+            if (!storage.queue.contains(imgSrc)) {
+                storage.queue.add(imgSrc);
+            }
+            if (storage.freeLoaders == 0) {
+                createLoader();
+            }
+
+            storage.queue.notify();
+        }
+    }
+
+    /**
+     * Waits for a new ImageSource until timout expires.
+     * Loader thread will terminate after returning from this method
+     * if timeout expired and image source was not picked up from the queue.
+     * @return image source picked up from the queue or null if timeout expired
+     */
+    private static DecodingImageSource getWaitingImageSource() {
+        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+
+        synchronized(storage.queue) {
+            DecodingImageSource isrc = null;
+
+            if (storage.queue.size() == 0) {
+                try {
+                    storage.freeLoaders++;
+                    storage.queue.wait(ImageLoadersStorage.TIMEOUT);
+                } catch (InterruptedException e) {
+                    return null;
+                } finally {
+                    storage.freeLoaders--;
+                }
+            }
+
+            if (storage.queue.size() > 0) {
+                isrc = storage.queue.get(0);
+                storage.queue.remove(0);
+            }
+
+            return isrc;
+        }
+    }
+
+    /**
+     * Entry point of the loader thread. Picks up image sources and
+     * runs decoders for them while there are available image sources in the queue.
+     * If there are no and timeout expires it terminates.
+     */
+    @Override
+    public void run() {
+        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+
+        try {
+            while (storage.loaders.contains(this)) {
+                Thread.interrupted(); // Reset the interrupted flag
+                DecodingImageSource isrc = getWaitingImageSource();
+                if (isrc != null) {
+                    try {
+                        isrc.load();
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                } else {
+                    break; // Don't wait if timeout expired - terminate loader
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            synchronized(storage.loaders) {
+                storage.loaders.remove(Thread.currentThread());
+            }
+        }
+    }
+
+    /**
+     * Removes current thread from loaders (so we are able
+     * to create more loaders) and decreases its priority.
+     */
+    static void beginAnimation() {
+        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+        Thread currThread = Thread.currentThread();
+
+        synchronized(storage) {
+            storage.loaders.remove(currThread);
+
+            if (storage.freeLoaders < storage.queue.size()) {
+                createLoader();
+            }
+        }
+
+        currThread.setPriority(Thread.MIN_PRIORITY);
+    }
+
+    /**
+     * Sends the current thread to wait for the new images to load
+     * if there are free placeholders for loaders
+     */
+    static void endAnimation() {
+        ImageLoadersStorage storage = ImageLoadersStorage.getStorage();
+        Thread currThread = Thread.currentThread();
+
+        synchronized(storage) {
+            if (storage.loaders.size() < ImageLoadersStorage.MAX_THREADS &&
+                    !storage.loaders.contains(currThread)
+            ) {
+                storage.loaders.add(currThread);
+            }
+        }
+
+        currThread.setPriority(Thread.NORM_PRIORITY);
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/JpegDecoder.java b/awt/org/apache/harmony/awt/gl/image/JpegDecoder.java
new file mode 100644
index 0000000..2e64427
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/JpegDecoder.java
@@ -0,0 +1,231 @@
+/*
+*  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 Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.image.*;
+import java.awt.color.ColorSpace;
+import java.awt.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class JpegDecoder extends ImageDecoder {
+    // Only 2 output colorspaces expected. Others are converted into
+    // these ones.
+    // 1. Grayscale
+    public static final int JCS_GRAYSCALE = 1;
+    // 2. RGB
+    public static final int JCS_RGB = 2;
+
+    // Flags for the consumer, progressive JPEG
+    private static final int hintflagsProgressive =
+            ImageConsumer.SINGLEFRAME | // JPEG is a static image
+            ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
+            ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
+    // Flags for the consumer, singlepass JPEG
+    private static final int hintflagsSingle =
+            ImageConsumer.SINGLEPASS |
+            hintflagsProgressive;
+
+    // Buffer for the stream
+    private static final int BUFFER_SIZE = 1024;
+    private byte buffer[] = new byte[BUFFER_SIZE];
+
+    // 3 possible color models only
+    private static ColorModel cmRGB;
+    private static ColorModel cmGray;
+
+    // initializes proper field IDs
+    private static native void initIDs();
+
+    // Pointer to native structure which store decoding state
+    // between subsequent decoding/IO-suspension cycles
+    private long hNativeDecoder = 0; // NULL initially
+
+    private boolean headerDone = false;
+
+    // Next 4 members are filled by the native method (decompress).
+    // We can simply check if imageWidth is still negative to find
+    // out if they are already filled.
+    private int imageWidth = -1;
+    private int imageHeight = -1;
+    private boolean progressive = false;
+    private int jpegColorSpace = 0;
+
+    // Stores number of bytes consumed by the native decoder
+    private int bytesConsumed = 0;
+    // Stores current scanline returned by the decoder
+    private int currScanline = 0;
+
+    private ColorModel cm = null;
+
+    static {
+        System.loadLibrary("jpegdecoder"); //$NON-NLS-1$
+
+        cmGray = new ComponentColorModel(
+                ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                false, false,
+                Transparency.OPAQUE, DataBuffer.TYPE_BYTE
+        );
+
+        // Create RGB color model
+        cmRGB = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);
+
+        initIDs();
+    }
+
+    public JpegDecoder(DecodingImageSource src, InputStream is) {
+        super(src, is);
+    }
+
+    /*
+    public JpegDecoder(InputStream iStream, ImageConsumer iConsumer) {
+    inputStream = iStream;
+    consumer = iConsumer;
+    }
+    */
+
+    /**
+     * @return - not NULL if call is successful
+     */
+    private native Object decode(
+            byte[] input,
+            int bytesInBuffer,
+            long hDecoder);
+
+    private static native void releaseNativeDecoder(long hDecoder);
+
+    @Override
+    public void decodeImage() throws IOException {
+        try {
+            int bytesRead = 0, dataLength = 0;
+            boolean eosReached = false;
+            int needBytes, offset, bytesInBuffer = 0;
+            byte byteOut[] = null;
+            int intOut[] = null;
+            // Read from the input stream
+            for (;;) {
+                needBytes = BUFFER_SIZE - bytesInBuffer;
+                offset = bytesInBuffer;
+
+                bytesRead = inputStream.read(buffer, offset, needBytes);
+
+                if (bytesRead < 0) {
+                    bytesRead = 0;//break;
+                    eosReached = true;
+                } // Don't break, maybe something left in buffer
+
+                // Keep track on how much bytes left in buffer
+                bytesInBuffer += bytesRead;
+
+                // Here we pass overall number of bytes left in the java buffer
+                // (bytesInBuffer) since jpeg decoder has its own buffer and consumes
+                // as many bytes as it can. If there are any unconsumed bytes
+                // it didn't add them to its buffer...
+                Object arr = decode(
+                        buffer,
+                        bytesInBuffer,
+                        hNativeDecoder);
+
+                // Keep track on how much bytes left in buffer
+                bytesInBuffer -= bytesConsumed;
+
+                if (!headerDone && imageWidth != -1) {
+                    returnHeader();
+                    headerDone = true;
+                }
+
+                if (bytesConsumed < 0) {
+                    break; // Error exit
+                }
+
+                if (arr instanceof byte[]) {
+                    byteOut = (byte[]) arr;
+                    dataLength = byteOut.length;
+                    returnData(byteOut, currScanline);
+                } else if (arr instanceof int[]) {
+                    intOut = (int[]) arr;
+                    dataLength = intOut.length;
+                    returnData(intOut, currScanline);
+                } else {
+                    dataLength = 0;
+                }
+
+                if (hNativeDecoder == 0) {
+                    break;
+                }
+
+                if (dataLength == 0 && eosReached) {
+                    releaseNativeDecoder(hNativeDecoder);
+                    break; // Probably image is truncated
+                }
+            }
+            imageComplete(ImageConsumer.STATICIMAGEDONE);
+        } catch (IOException e) {
+            throw e;
+        } finally {
+            closeStream();
+        }
+    }
+
+    public void returnHeader() {
+        setDimensions(imageWidth, imageHeight);
+
+        switch (jpegColorSpace) {
+            case JCS_GRAYSCALE: cm = cmGray; break;
+            case JCS_RGB: cm = cmRGB; break;
+            default: 
+                // awt.3D=Unknown colorspace
+                throw new IllegalArgumentException(Messages.getString("awt.3D")); //$NON-NLS-1$
+        }
+        setColorModel(cm);
+
+        setHints(progressive ? hintflagsProgressive : hintflagsSingle);
+
+        setProperties(new Hashtable<Object, Object>()); // Empty
+    }
+
+    // Send the data to the consumer
+    public void returnData(int data[], int currScanLine) {
+        // Send 1 or more scanlines to the consumer.
+        int numScanlines = data.length / imageWidth;
+        if (numScanlines > 0) {
+            setPixels(
+                    0, currScanLine - numScanlines,
+                    imageWidth, numScanlines,
+                    cm, data, 0, imageWidth
+            );
+        }
+    }
+
+    public void returnData(byte data[], int currScanLine) {
+        int numScanlines = data.length / imageWidth;
+        if (numScanlines > 0) {
+            setPixels(
+                    0, currScanLine - numScanlines,
+                    imageWidth, numScanlines,
+                    cm, data, 0, imageWidth
+            );
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/OffscreenImage.java b/awt/org/apache/harmony/awt/gl/image/OffscreenImage.java
new file mode 100644
index 0000000..3445f8e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/OffscreenImage.java
@@ -0,0 +1,532 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+/*
+ * Created on 22.12.2004
+ *
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.IndexColorModel;
+import java.awt.image.WritableRaster;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+
+/**
+ * This class represent implementation of abstract Image class
+ */
+public class OffscreenImage extends Image implements ImageConsumer {
+
+    static final ColorModel rgbCM = ColorModel.getRGBdefault();
+    ImageProducer src;
+    BufferedImage image;
+    ColorModel cm;
+    WritableRaster raster;
+    boolean isIntRGB;
+    Hashtable<?, ?> properties;
+    Vector<ImageObserver> observers;
+    int width;
+    int height;
+    int imageState;
+    int hints;
+    private boolean producing;
+    private ImageSurface imageSurf;
+
+    public OffscreenImage(ImageProducer ip){
+        imageState = 0;
+        src = ip;
+        width = -1;
+        height = -1;
+        observers = new Vector<ImageObserver>();
+        producing = false;
+    }
+
+    @Override
+    public Object getProperty(String name, ImageObserver observer) {
+        if(name == null) {
+            // awt.38=Property name is not defined
+            throw new NullPointerException(Messages.getString("awt.38")); //$NON-NLS-1$
+        }
+        if(properties == null){
+            addObserver(observer);
+            startProduction();
+            if(properties == null) {
+                return null;
+            }
+        }
+        Object prop = properties.get(name);
+        if(prop == null) {
+            prop = UndefinedProperty;
+        }
+        return prop;
+    }
+
+    @Override
+    public ImageProducer getSource() {
+        return src;
+    }
+
+    @Override
+    public int getWidth(ImageObserver observer) {
+        if((imageState & ImageObserver.WIDTH) == 0){
+            addObserver(observer);
+            startProduction();
+            if((imageState & ImageObserver.WIDTH) == 0) {
+                return -1;
+            }
+        }
+        return width;
+    }
+
+    @Override
+    public int getHeight(ImageObserver observer) {
+        if((imageState & ImageObserver.HEIGHT) == 0){
+            addObserver(observer);
+            startProduction();
+            if((imageState & ImageObserver.HEIGHT) == 0) {
+                return -1;
+            }
+        }
+        return height;
+    }
+
+    @Override
+    public Graphics getGraphics() {
+        // awt.39=This method is not implemented for image obtained from ImageProducer
+        throw new UnsupportedOperationException(Messages.getString("awt.39")); //$NON-NLS-1$
+    }
+
+    @Override
+    public void flush() {
+        stopProduction();
+        imageUpdate(this, ImageObserver.ABORT, -1, -1, -1, -1);
+        imageState &= ~ImageObserver.ERROR;
+        imageState = 0;
+        image = null;
+        cm = null;
+        raster = null;
+        hints = 0;
+        width = -1;
+        height = -1;
+    }
+
+    public void setProperties(Hashtable<?, ?> properties) {
+        this.properties = properties;
+        imageUpdate(this, ImageObserver.PROPERTIES, 0, 0, width, height);
+    }
+
+    public void setColorModel(ColorModel cm) {
+        this.cm = cm;
+    }
+
+    /*
+     * We suppose what in case loading JPEG image then image has DirectColorModel
+     * and for infill image Raster will use setPixels method with int array.
+     *
+     * In case loading GIF image, for raster infill, is used setPixels method with
+     * byte array and Color Model is IndexColorModel. But Color Model may
+     * be changed during this process. Then is called setPixels method with
+     * int array and image force to default color model - int ARGB. The rest
+     * pixels are sending in DirectColorModel.
+     */
+    public void setPixels(int x, int y, int w, int h, ColorModel model,
+            int[] pixels, int off, int scansize) {
+        if(raster == null){
+            if(cm == null){
+                if(model == null) {
+                    // awt.3A=Color Model is null
+                    throw new NullPointerException(Messages.getString("awt.3A")); //$NON-NLS-1$
+                }
+                cm = model;
+            }
+            createRaster();
+        }
+
+        if(model == null) {
+            model = cm;
+        }
+        if(cm != model){
+            forceToIntARGB();
+        }
+
+        if(cm == model && model.getTransferType() == DataBuffer.TYPE_INT &&
+                raster.getNumDataElements() == 1){
+
+            DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
+            int data[] = dbi.getData();
+            int scanline = raster.getWidth();
+            int rof = dbi.getOffset() + y * scanline + x;
+            for(int lineOff = off, line = y; line < y + h;
+                line++, lineOff += scansize, rof += scanline){
+
+                System.arraycopy(pixels, lineOff, data, rof, w);
+            }
+
+        }else if(isIntRGB){
+            int buff[] = new int[w];
+            DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
+            int data[] = dbi.getData();
+            int scanline = raster.getWidth();
+            int rof = dbi.getOffset() + y * scanline + x;
+            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize,
+                rof += scanline) {
+
+                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                    buff[idx] = model.getRGB(pixels[sOff + idx]);
+                }
+                System.arraycopy(buff, 0, data, rof, w);
+            }
+        }else{
+            Object buf = null;
+            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize) {
+                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                    int rgb = model.getRGB(pixels[sOff + idx]);
+                    buf = cm.getDataElements(rgb, buf);
+                    raster.setDataElements(sx, sy, buf);
+                }
+            }
+        }
+
+        if (imageSurf != null) {
+            imageSurf.invalidate();
+        }
+
+        imageUpdate(this, ImageObserver.SOMEBITS, 0, 0, width, height);
+    }
+
+    public void setPixels(int x, int y, int w, int h, ColorModel model,
+            byte[] pixels, int off, int scansize) {
+
+        if(raster == null){
+            if(cm == null){
+                if(model == null) {
+                    // awt.3A=Color Model is null
+                    throw new NullPointerException(Messages.getString("awt.3A")); //$NON-NLS-1$
+                }
+                cm = model;
+            }
+            createRaster();
+        }
+        if(model == null) {
+            model = cm;
+        }
+        if(model != cm){
+            forceToIntARGB();
+        }
+
+        if(isIntRGB){
+            int buff[] = new int[w];
+            IndexColorModel icm = (IndexColorModel) model;
+            int colorMap[] = new int[icm.getMapSize()];
+            icm.getRGBs(colorMap);
+            DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
+            int data[] = dbi.getData();
+            int scanline = raster.getWidth();
+            int rof = dbi.getOffset() + y * scanline + x;
+            if(model instanceof IndexColorModel){
+
+                for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize,
+                    rof += scanline) {
+                    for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                        buff[idx] = colorMap[pixels[sOff + idx] & 0xff];
+                    }
+                    System.arraycopy(buff, 0, data, rof, w);
+                }
+            }else{
+
+                for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize,
+                    rof += scanline) {
+                    for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                        buff[idx] = model.getRGB(pixels[sOff + idx] & 0xff);
+                    }
+                    System.arraycopy(buff, 0, data, rof, w);
+                }
+            }
+        }else if(model == cm && model.getTransferType() == DataBuffer.TYPE_BYTE &&
+                raster.getNumDataElements() == 1){
+
+            DataBufferByte dbb = (DataBufferByte)raster.getDataBuffer();
+            byte data[] = dbb.getData();
+            int scanline = raster.getWidth();
+            int rof = dbb.getOffset() + y * scanline + x;
+            for(int lineOff = off, line = y; line < y + h;
+                line++, lineOff += scansize, rof += scanline){
+                System.arraycopy(pixels, lineOff, data, rof, w);
+            }
+        // BEGIN android-added (taken from newer Harmony)
+        }else if(model == cm && model.getTransferType() == DataBuffer.TYPE_BYTE &&
+                cm instanceof ComponentColorModel){
+
+            int nc = cm.getNumComponents();
+            byte stride[] = new byte[scansize];
+            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize) {
+                System.arraycopy(pixels, sOff, stride, 0, scansize);
+                
+                raster.setDataElements(x, sy, w, 1, stride);
+            }
+        // END android-added
+        }else {
+            for (int sy = y, sOff = off; sy < y + h; sy++, sOff += scansize) {
+                for (int sx = x, idx = 0; sx < x + w; sx++, idx++) {
+                    int rgb = model.getRGB(pixels[sOff + idx] & 0xff);
+                    raster.setDataElements(sx, sy, cm.getDataElements(rgb, null));
+                }
+            }
+        }
+
+        if (imageSurf != null) {
+            imageSurf.invalidate();
+        }
+
+        imageUpdate(this, ImageObserver.SOMEBITS, 0, 0, width, height);
+    }
+
+    public void setDimensions(int width, int height) {
+        if(width <= 0 || height <= 0){
+            imageComplete(ImageObserver.ERROR);
+            return;
+        }
+
+        this.width = width;
+        this.height = height;
+        imageUpdate(this, (ImageObserver.HEIGHT | ImageObserver.WIDTH),
+                0, 0, width, height);
+    }
+
+    public void setHints(int hints) {
+        this.hints = hints;
+    }
+
+    public void imageComplete(int state) {
+        int flag;
+        switch(state){
+        case IMAGEABORTED:
+            flag = ImageObserver.ABORT;
+            break;
+        case IMAGEERROR:
+            flag = ImageObserver.ERROR | ImageObserver.ABORT;
+            break;
+        case SINGLEFRAMEDONE:
+            flag = ImageObserver.FRAMEBITS;
+            break;
+        case STATICIMAGEDONE:
+            flag = ImageObserver.ALLBITS;
+            break;
+        default:
+            // awt.3B=Incorrect ImageConsumer completion status
+            throw new IllegalArgumentException(Messages.getString("awt.3B")); //$NON-NLS-1$
+        }
+        imageUpdate(this, flag, 0, 0, width, height);
+
+        if((flag & (ImageObserver.ERROR | ImageObserver.ABORT |
+                ImageObserver.ALLBITS)) != 0 ) {
+            stopProduction();
+            observers.removeAllElements();
+        }
+    }
+
+    public /*synchronized*/ BufferedImage getBufferedImage(){
+        if(image == null){
+            ColorModel model = getColorModel();
+            WritableRaster wr = getRaster();
+            if(model != null && wr != null) {
+                image = new BufferedImage(model, wr, model.isAlphaPremultiplied(), null);
+            }
+        }
+        return image;
+    }
+
+    public /*synchronized*/ int checkImage(ImageObserver observer){
+        addObserver(observer);
+        return imageState;
+    }
+
+    public /*synchronized*/ boolean prepareImage(ImageObserver observer){
+        if((imageState & ImageObserver.ERROR) != 0){
+            if(observer != null){
+                observer.imageUpdate(this, ImageObserver.ERROR |
+                        ImageObserver.ABORT, -1, -1, -1, -1);
+            }
+            return false;
+        }
+        if((imageState & ImageObserver.ALLBITS) != 0) {
+            return true;
+        }
+        addObserver(observer);
+        startProduction();
+        return ((imageState & ImageObserver.ALLBITS) != 0);
+    }
+
+    public /*synchronized*/ ColorModel getColorModel(){
+        if(cm == null) {
+            startProduction();
+        }
+        return cm;
+    }
+
+    public /*synchronized*/ WritableRaster getRaster(){
+        if(raster == null) {
+            startProduction();
+        }
+        return raster;
+    }
+
+    public int getState(){
+        return imageState;
+    }
+
+    private /*synchronized*/ void addObserver(ImageObserver observer){
+        if(observer != null){
+          if(observers.contains(observer)) {
+            return;
+        }
+          if((imageState & ImageObserver.ERROR) != 0){
+              observer.imageUpdate(this, ImageObserver.ERROR |
+                      ImageObserver.ABORT, -1, -1, -1, -1);
+              return;
+          }
+          if((imageState & ImageObserver.ALLBITS) != 0){
+              observer.imageUpdate(this, imageState, 0, 0, width, height);
+              return;
+          }
+          observers.addElement(observer);
+        }
+    }
+
+    private synchronized void startProduction(){
+        if(!producing){
+            imageState &= ~ImageObserver.ABORT;
+            producing = true;
+            src.startProduction(this);
+        }
+    }
+
+    private synchronized void stopProduction(){
+        producing = false;
+        src.removeConsumer(this);
+    }
+
+    private void createRaster(){
+        try{
+            raster = cm.createCompatibleWritableRaster(width, height);
+            isIntRGB = false;
+            if(cm instanceof DirectColorModel){
+                DirectColorModel dcm = (DirectColorModel) cm;
+                if(dcm.getTransferType() == DataBuffer.TYPE_INT &&
+                        dcm.getRedMask() == 0xff0000 &&
+                        dcm.getGreenMask() == 0xff00 &&
+                        dcm.getBlueMask() == 0xff){
+                    isIntRGB = true;
+                }
+            }
+        }catch(Exception e){
+            cm = ColorModel.getRGBdefault();
+            raster = cm.createCompatibleWritableRaster(width, height);
+            isIntRGB = true;
+        }
+    }
+
+    private /*synchronized*/ void imageUpdate(Image img, int infoflags, int x, int y,
+            int width, int height){
+
+        imageState |= infoflags;
+        for (ImageObserver observer : observers) {
+            observer.imageUpdate(this, infoflags, x, y, width, height);
+        }
+
+//            notifyAll();
+    }
+
+    private void forceToIntARGB(){
+
+        int w = raster.getWidth();
+        int h = raster.getHeight();
+
+        WritableRaster destRaster = rgbCM.createCompatibleWritableRaster(w, h);
+
+        Object obj = null;
+        int pixels[] = new int[w];
+
+        if(cm instanceof IndexColorModel){
+            IndexColorModel icm = (IndexColorModel) cm;
+            int colorMap[] = new int[icm.getMapSize()];
+            icm.getRGBs(colorMap);
+
+            for (int y = 0; y < h; y++) {
+                obj = raster.getDataElements(0, y, w, 1, obj);
+                byte ba[] = (byte[]) obj;
+                for (int x = 0; x < ba.length; x++) {
+                    pixels[x] = colorMap[ba[x] & 0xff];
+                }
+                destRaster.setDataElements(0, y, w, 1, pixels);
+            }
+
+        }else{
+            for(int y = 0; y < h; y++){
+                for(int x = 0; x < w; x++){
+                    obj = raster.getDataElements(x, y, obj);
+                    pixels[x] = cm.getRGB(obj);
+                }
+                destRaster.setDataElements(0, y, w, 1, pixels);
+            }
+        }
+
+        synchronized(this){
+            if(imageSurf != null){
+                imageSurf.dispose();
+                imageSurf = null;
+            }
+            if(image != null){
+                image.flush();
+                image = null;
+            }
+            cm = rgbCM;
+            raster = destRaster;
+            isIntRGB = true;
+        }
+    }
+
+    public ImageSurface getImageSurface() {
+        if (imageSurf == null) {
+            ColorModel model = getColorModel();
+            WritableRaster wr = getRaster();
+            if(model != null && wr != null) {
+                imageSurf = new ImageSurface(model, wr);
+            }
+        }
+        return imageSurf;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/OrdinaryWritableRaster.java b/awt/org/apache/harmony/awt/gl/image/OrdinaryWritableRaster.java
new file mode 100644
index 0000000..1748e1b
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/OrdinaryWritableRaster.java
@@ -0,0 +1,153 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+/*
+ * Created on 30.09.2004
+ *
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+
+public class OrdinaryWritableRaster extends WritableRaster {
+
+    public OrdinaryWritableRaster(SampleModel sampleModel,
+            DataBuffer dataBuffer, Rectangle aRegion,
+            Point sampleModelTranslate, WritableRaster parent) {
+        super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
+    }
+
+    public OrdinaryWritableRaster(SampleModel sampleModel,
+            DataBuffer dataBuffer, Point origin) {
+        super(sampleModel, dataBuffer, origin);
+    }
+
+    public OrdinaryWritableRaster(SampleModel sampleModel, Point origin) {
+        super(sampleModel, origin);
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Object inData) {
+        super.setDataElements(x, y, inData);
+    }
+
+    @Override
+    public void setDataElements(int x, int y, int w, int h, Object inData) {
+        super.setDataElements(x, y, w, h, inData);
+    }
+
+    @Override
+    public WritableRaster createWritableChild(int parentX, int parentY, int w,
+            int h, int childMinX, int childMinY, int[] bandList) {
+        return super.createWritableChild(parentX, parentY, w, h, childMinX,
+                childMinY, bandList);
+    }
+
+    @Override
+    public WritableRaster createWritableTranslatedChild(int childMinX,
+            int childMinY) {
+        return super.createWritableTranslatedChild(childMinX, childMinY);
+    }
+
+    @Override
+    public WritableRaster getWritableParent() {
+        return super.getWritableParent();
+    }
+
+    @Override
+    public void setRect(Raster srcRaster) {
+        super.setRect(srcRaster);
+    }
+
+    @Override
+    public void setRect(int dx, int dy, Raster srcRaster) {
+        super.setRect(dx, dy, srcRaster);
+    }
+
+    @Override
+    public void setDataElements(int x, int y, Raster inRaster) {
+        super.setDataElements(x, y, inRaster);
+    }
+
+    @Override
+    public void setPixel(int x, int y, int[] iArray) {
+        super.setPixel(x, y, iArray);
+    }
+
+    @Override
+    public void setPixel(int x, int y, float[] fArray) {
+        super.setPixel(x, y, fArray);
+    }
+
+    @Override
+    public void setPixel(int x, int y, double[] dArray) {
+        super.setPixel(x, y, dArray);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, int[] iArray) {
+        super.setPixels(x, y, w, h, iArray);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, float[] fArray) {
+        super.setPixels(x, y, w, h, fArray);
+    }
+
+    @Override
+    public void setPixels(int x, int y, int w, int h, double[] dArray) {
+        super.setPixels(x, y, w, h, dArray);
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, int[] iArray) {
+        super.setSamples(x, y, w, h, b, iArray);
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, float[] fArray) {
+        super.setSamples(x, y, w, h, b, fArray);
+    }
+
+    @Override
+    public void setSamples(int x, int y, int w, int h, int b, double[] dArray) {
+        super.setSamples(x, y, w, h, b, dArray);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, int s) {
+        super.setSample(x, y, b, s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, float s) {
+        super.setSample(x, y, b, s);
+    }
+
+    @Override
+    public void setSample(int x, int y, int b, double s) {
+        super.setSample(x, y, b, s);
+    }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/PngDecoder.java b/awt/org/apache/harmony/awt/gl/image/PngDecoder.java
new file mode 100644
index 0000000..7e85600
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/PngDecoder.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 Oleg V. Khaschansky
+ * @version $Revision$
+ *
+ * @date: Jul 22, 2005
+ */
+
+package org.apache.harmony.awt.gl.image;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.awt.color.ColorSpace;
+import java.awt.image.*;
+import java.awt.*;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class PngDecoder extends ImageDecoder {
+    // initializes proper field IDs
+    private static native void initIDs();
+
+    static {
+        System.loadLibrary("gl"); //$NON-NLS-1$
+        initIDs();
+    }
+
+    private static final int hintflags =
+            ImageConsumer.SINGLEFRAME | // PNG is a static image
+            ImageConsumer.TOPDOWNLEFTRIGHT | // This order is only one possible
+            ImageConsumer.COMPLETESCANLINES; // Don't deliver incomplete scanlines
+
+    // Each pixel is a grayscale sample.
+    private static final int PNG_COLOR_TYPE_GRAY = 0;
+    // Each pixel is an R,G,B triple.
+    private static final int PNG_COLOR_TYPE_RGB = 2;
+    // Each pixel is a palette index, a PLTE chunk must appear.
+    private static final int PNG_COLOR_TYPE_PLTE = 3;
+    // Each pixel is a grayscale sample, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
+    // Each pixel is an R,G,B triple, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_RGBA = 6;
+
+    private static final int INPUT_BUFFER_SIZE = 4096;
+    private byte buffer[] = new byte[INPUT_BUFFER_SIZE];
+
+    // Buffers for decoded image data
+    byte byteOut[];
+    int intOut[];
+
+    // Native pointer to png decoder data
+    private long hNativeDecoder;
+
+    int imageWidth, imageHeight;
+    int colorType;
+    int bitDepth;
+    byte cmap[];
+
+    boolean transferInts; // Is transfer type int?.. or byte?
+    int dataElementsPerPixel = 1;
+
+    ColorModel cm;
+
+    int updateFromScanline; // First scanline to update
+    int numScanlines; // Number of scanlines to update
+
+    private native long decode(byte[] input, int bytesInBuffer, long hDecoder);
+
+    private static native void releaseNativeDecoder(long hDecoder);
+
+    public PngDecoder(DecodingImageSource src, InputStream is) {
+        super(src, is);
+    }
+
+    @Override
+    public void decodeImage() throws IOException {
+        try {
+            int bytesRead = 0;
+            int needBytes, offset, bytesInBuffer = 0;
+            // Read from the input stream
+            for (;;) {
+                needBytes = INPUT_BUFFER_SIZE - bytesInBuffer;
+                offset = bytesInBuffer;
+
+                bytesRead = inputStream.read(buffer, offset, needBytes);
+
+                if (bytesRead < 0) { // Break, nothing to read from buffer, image truncated?
+                    releaseNativeDecoder(hNativeDecoder);
+                    break;
+                }
+
+                // Keep track on how much bytes left in buffer
+                bytesInBuffer += bytesRead;
+                hNativeDecoder = decode(buffer, bytesInBuffer, hNativeDecoder);
+                // PNG decoder always consumes all bytes at once
+                bytesInBuffer = 0;
+
+                // if (bytesConsumed < 0)
+                //break; // Error exit
+
+                returnData();
+
+                // OK, we decoded all the picture in the right way...
+                if (hNativeDecoder == 0) {
+                    break;
+                }
+            }
+
+            imageComplete(ImageConsumer.STATICIMAGEDONE);
+        } catch (IOException e) {
+            throw e;
+        } catch (RuntimeException e) {
+            imageComplete(ImageConsumer.IMAGEERROR);
+            throw e;
+        } finally {
+            closeStream();
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private void returnHeader() { // Called from native code
+        setDimensions(imageWidth, imageHeight);
+
+        switch (colorType) {
+            case PNG_COLOR_TYPE_GRAY: {
+                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                // Create gray color model
+                int numEntries = 1 << bitDepth;
+                int scaleFactor = 255 / (numEntries-1);
+                byte comps[] = new byte[numEntries];
+                for (int i = 0; i < numEntries; i++) {
+                    comps[i] = (byte) (i * scaleFactor);
+                }
+                cm = new IndexColorModel(/*bitDepth*/8, numEntries, comps, comps, comps);
+
+                transferInts = false;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_RGB: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);
+
+                transferInts = true;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_PLTE: {
+                if (bitDepth != 8 && bitDepth != 4 && bitDepth != 2 && bitDepth != 1) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = new IndexColorModel(/*bitDepth*/8, cmap.length / 3, cmap, 0, false);
+
+                transferInts = false;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_GRAY_ALPHA: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
+                        true, false,
+                        Transparency.TRANSLUCENT,
+                        DataBuffer.TYPE_BYTE);
+
+                transferInts = false;
+                dataElementsPerPixel = 2;
+                break;
+            }
+
+            case PNG_COLOR_TYPE_RGBA: {
+                if (bitDepth != 8) {
+                    // awt.3C=Unknown PNG color type
+                    throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+                }
+
+                cm = ColorModel.getRGBdefault();
+
+                transferInts = true;
+                break;
+            }
+            default:
+                // awt.3C=Unknown PNG color type
+                throw new IllegalArgumentException(Messages.getString("awt.3C")); //$NON-NLS-1$
+        }
+
+        // Create output buffer
+        if (transferInts) {
+            intOut = new int[imageWidth * imageHeight];
+        } else {
+            byteOut = new byte[imageWidth * imageHeight * dataElementsPerPixel];
+        }
+
+        setColorModel(cm);
+
+        setHints(hintflags);
+        setProperties(new Hashtable<Object, Object>()); // Empty
+    }
+
+    // Send the data to the consumer
+    private void returnData() {
+        // Send 1 or more scanlines to the consumer.
+        if (numScanlines > 0) {
+            // Native decoder could have returned
+            // some data from the next pass, handle it here
+            int pass1, pass2;
+            if (updateFromScanline + numScanlines > imageHeight) {
+                pass1 = imageHeight - updateFromScanline;
+                pass2 = updateFromScanline + numScanlines - imageHeight;
+            } else {
+                pass1 = numScanlines;
+                pass2 = 0;
+            }
+
+            transfer(updateFromScanline, pass1);
+            if (pass2 != 0) {
+                transfer(0, pass2);
+            }
+        }
+    }
+
+    private void transfer(int updateFromScanline, int numScanlines) {
+        if (transferInts) {
+            setPixels(
+                    0, updateFromScanline,
+                    imageWidth, numScanlines,
+                    cm, intOut,
+                    updateFromScanline * imageWidth,
+                    imageWidth
+            );
+        } else {
+            setPixels(
+                    0, updateFromScanline,
+                    imageWidth, numScanlines,
+                    cm, byteOut,
+                    updateFromScanline * imageWidth * dataElementsPerPixel,
+                    imageWidth * dataElementsPerPixel
+            );
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/gl/image/PngDecoderJava.java b/awt/org/apache/harmony/awt/gl/image/PngDecoderJava.java
new file mode 100644
index 0000000..46545f9
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/PngDecoderJava.java
@@ -0,0 +1,282 @@
+package org.apache.harmony.awt.gl.image;
+
+// A simple PNG decoder source code in Java.
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.zip.CRC32;
+import java.util.zip.InflaterInputStream;
+
+//import javax.swing.JFrame;
+
+public class PngDecoderJava {
+ 
+/*
+  public static void main(String[] args) throws Exception {
+    String name = "logo.png";
+    if (args.length > 0)
+      name = args[0];
+    InputStream in = PngDecoderJava.class.getResourceAsStream(name);
+    final BufferedImage image = PngDecoderJava.decode(in);
+    in.close();
+
+    JFrame f = new JFrame() {
+      public void paint(Graphics g) {
+        Insets insets = getInsets();
+        g.drawImage(image, insets.left, insets.top, null);
+      }
+    };
+    f.setVisible(true);
+    Insets insets = f.getInsets();
+    f.setSize(image.getWidth() + insets.left + insets.right, image
+        .getHeight()
+        + insets.top + insets.bottom);
+  }
+  */
+
+  public static BufferedImage decode(InputStream in) throws IOException {
+    DataInputStream dataIn = new DataInputStream(in);
+    readSignature(dataIn);
+    PNGData chunks = readChunks(dataIn);
+
+    long widthLong = chunks.getWidth();
+    long heightLong = chunks.getHeight();
+    if (widthLong > Integer.MAX_VALUE || heightLong > Integer.MAX_VALUE)
+      throw new IOException("That image is too wide or tall.");
+    int width = (int) widthLong;
+    int height = (int) heightLong;
+
+    ColorModel cm = chunks.getColorModel();
+    WritableRaster raster = chunks.getRaster();
+
+    BufferedImage image = new BufferedImage(cm, raster, false, null);
+
+    return image;
+  }
+
+  protected static void readSignature(DataInputStream in) throws IOException {
+    long signature = in.readLong();
+    if (signature != 0x89504e470d0a1a0aL)
+      throw new IOException("PNG signature not found!");
+  }
+
+  protected static PNGData readChunks(DataInputStream in) throws IOException {
+    PNGData chunks = new PNGData();
+
+    boolean trucking = true;
+    while (trucking) {
+      try {
+        // Read the length.
+        int length = in.readInt();
+        if (length < 0)
+          throw new IOException("Sorry, that file is too long.");
+        // Read the type.
+        byte[] typeBytes = new byte[4];
+        in.readFully(typeBytes);
+        // Read the data.
+        byte[] data = new byte[length];
+        in.readFully(data);
+        // Read the CRC.
+        long crc = in.readInt() & 0x00000000ffffffffL; // Make it
+        // unsigned.
+        if (verifyCRC(typeBytes, data, crc) == false)
+          throw new IOException("That file appears to be corrupted.");
+
+        PNGChunk chunk = new PNGChunk(typeBytes, data);
+        chunks.add(chunk);
+      } catch (EOFException eofe) {
+        trucking = false;
+      }
+    }
+    return chunks;
+  }
+
+  protected static boolean verifyCRC(byte[] typeBytes, byte[] data, long crc) {
+    CRC32 crc32 = new CRC32();
+    crc32.update(typeBytes);
+    crc32.update(data);
+    long calculated = crc32.getValue();
+    return (calculated == crc);
+  }
+}
+
+class PNGData {
+  private int mNumberOfChunks;
+
+  private PNGChunk[] mChunks;
+
+  public PNGData() {
+    mNumberOfChunks = 0;
+    mChunks = new PNGChunk[10];
+  }
+
+  public void add(PNGChunk chunk) {
+    mChunks[mNumberOfChunks++] = chunk;
+    if (mNumberOfChunks >= mChunks.length) {
+      PNGChunk[] largerArray = new PNGChunk[mChunks.length + 10];
+      System.arraycopy(mChunks, 0, largerArray, 0, mChunks.length);
+      mChunks = largerArray;
+    }
+  }
+
+  public long getWidth() {
+    return getChunk("IHDR").getUnsignedInt(0);
+  }
+
+  public long getHeight() {    return getChunk("IHDR").getUnsignedInt(4);
+  }
+
+  public short getBitsPerPixel() {
+    return getChunk("IHDR").getUnsignedByte(8);
+  }
+
+  public short getColorType() {
+    return getChunk("IHDR").getUnsignedByte(9);
+  }
+
+  public short getCompression() {
+    return getChunk("IHDR").getUnsignedByte(10);
+  }
+
+  public short getFilter() {
+    return getChunk("IHDR").getUnsignedByte(11);
+  }
+
+  public short getInterlace() {
+    return getChunk("IHDR").getUnsignedByte(12);
+  }
+
+  public ColorModel getColorModel() {
+    short colorType = getColorType();
+    int bitsPerPixel = getBitsPerPixel();
+
+    if (colorType == 3) {
+      byte[] paletteData = getChunk("PLTE").getData();
+      int paletteLength = paletteData.length / 3;
+      return new IndexColorModel(bitsPerPixel, paletteLength,
+          paletteData, 0, false);
+    }
+    System.out.println("Unsupported color type: " + colorType);
+    return null;
+  }
+
+  public WritableRaster getRaster() {
+    int width = (int) getWidth();
+    int height = (int) getHeight();
+    int bitsPerPixel = getBitsPerPixel();
+    short colorType = getColorType();
+
+    if (colorType == 3) {
+      byte[] imageData = getImageData();
+      //Orig: DataBuffer db = new DataBufferByte(imageData, imageData.length);
+      int len = Math.max(imageData.length, (width - 1) * (height -1));
+      DataBuffer db = new DataBufferByte(imageData, len);
+      WritableRaster raster = Raster.createPackedRaster(db, width,
+          height, bitsPerPixel, null);
+      return raster;
+    } else
+      System.out.println("Unsupported color type!");
+    return null;
+  }
+
+  public byte[] getImageData() {
+    try {
+      ByteArrayOutputStream out = new ByteArrayOutputStream();
+      // Write all the IDAT data into the array.
+      for (int i = 0; i < mNumberOfChunks; i++) {
+        PNGChunk chunk = mChunks[i];
+        if (chunk.getTypeString().equals("IDAT")) {
+          out.write(chunk.getData());
+        }
+      }
+      out.flush();
+      // Now deflate the data.
+      InflaterInputStream in = new InflaterInputStream(
+          new ByteArrayInputStream(out.toByteArray()));
+      ByteArrayOutputStream inflatedOut = new ByteArrayOutputStream();
+      int readLength;
+      byte[] block = new byte[8192];
+      while ((readLength = in.read(block)) != -1)
+        inflatedOut.write(block, 0, readLength);
+      inflatedOut.flush();
+      byte[] imageData = inflatedOut.toByteArray();
+      // Compute the real length.
+      int width = (int) getWidth();
+      int height = (int) getHeight();
+      int bitsPerPixel = getBitsPerPixel();
+      int length = width * height * bitsPerPixel / 8;
+
+      byte[] prunedData = new byte[length];
+
+      // We can only deal with non-interlaced images.
+      if (getInterlace() == 0) {
+        int index = 0;
+        for (int i = 0; i < length; i++) {
+          if ((i * 8 / bitsPerPixel) % width == 0) {
+            index++; // Skip the filter byte.
+          }
+          prunedData[i] = imageData[index++];
+        }
+      } else
+        System.out.println("Couldn't undo interlacing.");
+
+      return prunedData;
+    } catch (IOException ioe) {
+    }
+    return null;
+  }
+
+  public PNGChunk getChunk(String type) {
+    for (int i = 0; i < mNumberOfChunks; i++)
+      if (mChunks[i].getTypeString().equals(type))
+        return mChunks[i];
+    return null;
+  }
+}
+
+class PNGChunk {
+  private byte[] mType;
+
+  private byte[] mData;
+
+  public PNGChunk(byte[] type, byte[] data) {
+    mType = type;
+    mData = data;
+  }
+
+  public String getTypeString() {
+    try {
+      return new String(mType, "UTF8");
+    } catch (UnsupportedEncodingException uee) {
+      return "";
+    }
+  }
+
+  public byte[] getData() {
+    return mData;
+  }
+
+  public long getUnsignedInt(int offset) {
+    long value = 0;
+    for (int i = 0; i < 4; i++)
+      value += (mData[offset + i] & 0xff) << ((3 - i) * 8);
+    return value;
+  }
+
+  public short getUnsignedByte(int offset) {
+    return (short) (mData[offset] & 0x00ff);
+  }
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java
new file mode 100644
index 0000000..a1899d6
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java
@@ -0,0 +1,77 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ */
+/*
+ * Created on 10.02.2005
+ *
+ */
+package org.apache.harmony.awt.gl.image;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.Permission;
+
+public class URLDecodingImageSource extends DecodingImageSource {
+
+    URL url;
+
+    public URLDecodingImageSource(URL url){
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkConnect(url.getHost(), url.getPort());
+            try {
+                Permission p = url.openConnection().getPermission();
+                security.checkPermission(p);
+            } catch (IOException e) {
+            }
+        }
+        this.url = url;
+    }
+
+    @Override
+    protected boolean checkConnection() {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            try {
+                security.checkConnect(url.getHost(), url.getPort());
+                return true;
+            } catch (SecurityException e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    protected InputStream getInputStream() {
+        try{
+            URLConnection uc = url.openConnection();
+            // BEGIN android-modified
+            return new BufferedInputStream(uc.getInputStream(), 8192);
+            // END android-modified
+        }catch(IOException e){
+            return null;
+        }
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/Blitter.java b/awt/org/apache/harmony/awt/gl/render/Blitter.java
new file mode 100644
index 0000000..3b8012e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/Blitter.java
@@ -0,0 +1,53 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 14.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.geom.AffineTransform;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+
+/**
+ * The interface for objects which can drawing Images on other Images which have 
+ * Graphics or on the display.  
+ */
+public interface Blitter {
+
+    public abstract void blit(int srcX, int srcY, Surface srcSurf,
+            int dstX, int dstY, Surface dstSurf, int width, int height,
+            AffineTransform sysxform, AffineTransform xform,
+            Composite comp, Color bgcolor,
+            MultiRectArea clip);
+
+    public abstract void blit(int srcX, int srcY, Surface srcSurf,
+            int dstX, int dstY, Surface dstSurf, int width, int height,
+            AffineTransform sysxform, Composite comp, Color bgcolor,
+            MultiRectArea clip);
+
+    public abstract void blit(int srcX, int srcY, Surface srcSurf,
+            int dstX, int dstY, Surface dstSurf, int width, int height,
+            Composite comp, Color bgcolor, MultiRectArea clip);
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaArcRasterizer.java b/awt/org/apache/harmony/awt/gl/render/JavaArcRasterizer.java
new file mode 100644
index 0000000..b643b41
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/JavaArcRasterizer.java
@@ -0,0 +1,502 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.render;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+
+public class JavaArcRasterizer {
+
+    /**
+     * Adds particular arc segment to mra 
+     */
+    static void addX0LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int x1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x2 = line[i];
+            int y = cy + (b - i);
+            if (x1 <= finish && x2 >= start) {
+                mra.addRect(cx + Math.max(x1, start), y, cx + Math.min(x2, finish), y);
+            }
+            x1 = x2 + 1;
+        }
+    }
+
+    static void addX1LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int x1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x2 = line[i];
+            int y = cy - (b - i);
+            if (x1 <= finish && x2 >= start) {
+                mra.addRect(cx + Math.max(x1, start), y, cx + Math.min(x2, finish), y);
+            }
+            x1 = x2 + 1;
+        }
+    }
+
+    static void addX2LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int x1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x2 = line[i];
+            int y = cy - (b - i);
+            if (x1 <= finish && x2 >= start) {
+                mra.addRect(cx - Math.min(x2, finish), y, cx - Math.max(x1, start), y);
+            }
+            x1 = x2 + 1;
+        }
+    }
+
+    static void addX3LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int x1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x2 = line[i];
+            int y = cy + (b - i);
+            if (x1 <= finish && x2 >= start) {
+                mra.addRect(cx - Math.min(x2, finish), y, cx - Math.max(x1, start), y);
+            }
+            x1 = x2 + 1;
+        }
+    }
+
+    static void addY0LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int y1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x = cx + (b - i);
+            int y2 = line[i];
+            if (y1 <= finish && y2 >= start) {
+                mra.addRect(x, cy + Math.max(y1, start), x, cy + Math.min(y2, finish));
+            }
+            y1 = y2 + 1;
+        }
+    }
+
+    static void addY1LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int y1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x = cx - (b - i);
+            int y2 = line[i];
+            if (y1 <= finish && y2 >= start) {
+                mra.addRect(x, cy + Math.max(y1, start), x, cy + Math.min(y2, finish));
+            }
+            y1 = y2 + 1;
+        }
+    }
+
+    static void addY2LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int y1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x = cx - (b - i);
+            int y2 = line[i];
+            if (y1 <= finish && y2 >= start) {
+                mra.addRect(x, cy - Math.min(y2, finish), x, cy - Math.max(y1, start));
+            }
+            y1 = y2 + 1;
+        }
+    }
+
+    static void addY3LineSeg(MultiRectArea mra, int[] line, int cx, int cy, int b, int start, int finish) {
+        int y1 = 0;
+        for(int i = 0; i < line.length; i++) {
+            int x = cx + (b - i);
+            int y2 = line[i];
+            if (y1 <= finish && y2 >= start) {
+                mra.addRect(x, cy - Math.min(y2, finish), x, cy - Math.max(y1, start));
+            }
+            y1 = y2 + 1;
+        }
+    }
+
+    static void addX0Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx + prev, cy + (b - i), cx + line[i], cy + (b - i));
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addX1Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx + prev, cy - (b - i), cx + line[i], cy - (b - i));
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addX2Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx - line[i], cy - (b - i), cx - prev, cy - (b - i));
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addX3Line(MultiRectArea mra, int[] line, int cx, int cy, int b) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx - line[i], cy + (b - i), cx - prev, cy + (b - i));
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addY0Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx + (a - i), cy + prev, cx + (a - i), cy + line[i]);
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addY1Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx - (a - i), cy + prev, cx - (a - i), cy + line[i]);
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addY2Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx - (a - i), cy - line[i], cx - (a - i), cy - prev);
+            prev = line[i] + 1;
+        }
+    }
+
+    static void addY3Line(MultiRectArea mra, int[] line, int cx, int cy, int a) {
+        int prev = 0;
+        for(int i = 0; i < line.length; i++) {
+            mra.addRect(cx + (a - i), cy - line[i], cx + (a - i), cy - prev);
+            prev = line[i] + 1;
+        }
+    }
+
+    /**
+     * Returns normalized angle (from 0 to 360 degrees)
+     */
+    static double getNormAngle(double angle) {
+        angle -= Math.floor(angle / 360) * 360;
+        if (angle < 0) {
+            angle += 360;
+        }
+        return angle;
+    }
+
+    /**
+     * Creates arc lookup table
+     */
+    static int[] createLine(int a, int b, int xcount, int ycount) {
+        int[] buf = new int[b - ycount + 1];
+        int d = a * a + 2 * b * b - 2 * a * a * b;
+        int x = 0;
+        int y = b;
+        while (y >= ycount) {
+            if (d < 0) {
+                d = d + b * b * (4 * x + 6);
+            } else {
+                buf[b - y] = x;
+                d = d + b * b * (4 * x + 6) + 4 * a * a * (1 - y);
+                y--;
+            }
+            x++;
+        }
+        return buf;
+    }
+
+    /**
+     * Adds head/tail arc segment to MultiRectArea
+     */
+    static void addSeg(MultiRectArea mra, int cx1, int cy1, int cx2, int cy2, int a, int b, int[] xline, int[] yline, int[] bounds) {
+        switch(bounds[0]) {
+        case 0:
+            addY3LineSeg(mra, yline, cx2, cy1, a, bounds[1], bounds[2]);
+            break;
+        case 1:
+            addX1LineSeg(mra, xline, cx2, cy1, b, bounds[1], bounds[2]);
+            break;
+        case 2:
+            addX2LineSeg(mra, xline, cx1, cy1, b, bounds[1], bounds[2]);
+            break;
+        case 3:
+            addY2LineSeg(mra, yline, cx1, cy1, a, bounds[1], bounds[2]);
+            break;
+        case 4:
+            addY1LineSeg(mra, yline, cx1, cy2, a, bounds[1], bounds[2]);
+            break;
+        case 5:
+            addX3LineSeg(mra, xline, cx1, cy2, b, bounds[1], bounds[2]);
+            break;
+        case 6:
+            addX0LineSeg(mra, xline, cx2, cy2, b, bounds[1], bounds[2]);
+            break;
+        case 7:
+            addY0LineSeg(mra, yline, cx2, cy2, a, bounds[1], bounds[2]);
+            break;
+        }
+    }
+
+    /**
+     * Returns bounds for non quadratic arc head
+     */
+    static int[] getSegment1(double angle, int ax, int ay, int xcount, int ycount) {
+        int[] bounds = new int[3];
+        switch((int)(angle / 90)) {
+        case 0:
+            if (xcount <  ax) {
+                bounds[0] = 0; // Y3
+                bounds[1] = -ay;
+                bounds[2] = ycount;
+            } else {
+                bounds[0] = 1; // X1
+                bounds[1] = 0;
+                bounds[2] = ax;
+            }
+            break;
+        case 1:
+            if (xcount > -ax) {
+                bounds[0] = 2; // X2
+                bounds[1] = -ax;
+                bounds[2] = xcount;
+            } else {
+                bounds[0] = 3; // Y2
+                bounds[1] = 0;
+                bounds[2] = -ay;
+            }
+            break;
+        case 2:
+            if (xcount < -ax) {
+                bounds[0] = 4; // Y1
+                bounds[1] = ay;
+                bounds[2] = ycount;
+            } else {
+                bounds[0] = 5; // X3
+                bounds[1] = 0;
+                bounds[2] = -ax;
+            }
+            break;
+        case 3:
+            if (xcount >  ax) {
+                bounds[0] = 6; // X0
+                bounds[1] = ax;
+                bounds[2] = xcount;
+            } else {
+                bounds[0] = 7; // Y0
+                bounds[1] = 0;
+                bounds[2] = ay;
+            }
+            break;
+        }
+        return bounds;
+    }
+
+    /**
+     * Returns bounds for non quadratic arc tail
+     */
+    static int[] getSegment2(double angle, int ax, int ay, int xcount, int ycount) {
+        int[] bounds = new int[3];
+        switch((int)(angle / 90)) {
+        case 0:
+            if (xcount <  ax) {
+                bounds[0] = 0; // Y3
+                bounds[1] = 0;
+                bounds[2] = -ay;
+            } else {
+                bounds[0] = 1; // X1
+                bounds[1] = ax;
+                bounds[2] = xcount;
+            }
+            break;
+        case 1:
+            if (xcount > -ax) {
+                bounds[0] = 2; // X2
+                bounds[1] = 0;
+                bounds[2] = -ax;
+            } else {
+                bounds[0] = 3; // Y2
+                bounds[1] = -ay;
+                bounds[2] = ycount;
+            }
+            break;
+        case 2:
+            if (xcount < -ax) {
+                bounds[0] = 4; // Y1
+                bounds[1] = 0;
+                bounds[2] = ay;
+            } else {
+                bounds[0] = 5; // X3
+                bounds[1] = -ax;
+                bounds[2] = xcount;
+            }
+            break;
+        case 3:
+            if (xcount >  ax) {
+                bounds[0] = 6; // X0
+                bounds[1] = 0;
+                bounds[2] = ax;
+            } else {
+                bounds[0] = 7; // Y0
+                bounds[1] = ay;
+                bounds[2] = ycount;
+            }
+            break;
+        }
+        return bounds;
+    }
+
+    /**
+     * Rasterizes arc using clippind and dashing style
+     * @param x1 - the x coordinate of the left-upper corner of the arc bounds
+     * @param y1 - the y coordinate of the left-upper corner of the arc bounds
+     * @param width - the width of the arc bounds
+     * @param height - the height of the arc bounds
+     * @param angleStart - the start angle of the arc in degrees
+     * @param angleExtent - the angle extent in degrees
+     * @param clip - the MultiRectArea object of clipping area
+     * @return a MultiRectArea of rasterizer arc
+     */
+    public static MultiRectArea rasterize(int x, int y, int width, int height, double angleStart, double angleExtent, MultiRectArea clip) {
+
+        MultiRectArea mra = new MultiRectArea(false);
+
+        int cx1, cx2, cy1, cy2;
+        cx1 = cx2 = x + width / 2;
+        cy1 = cy2 = y + height / 2;
+
+        if (width % 2 == 0) {
+            cx2--;
+        }
+
+        if (height % 2 == 0) {
+            cy2--;
+        }
+
+        int a = width / 2;
+        int b = height / 2;
+        double c = Math.sqrt(a * a + b * b);
+
+        int xcount, ycount;
+        if (a < b) {
+            xcount = (int)Math.ceil(a * a / c);
+            ycount = (int)Math.floor(b * b / c);
+        } else {
+            xcount = (int)Math.floor(a * a / c);
+            ycount = (int)Math.ceil(b * b / c);
+        }
+
+        int[] xline = createLine(a, b, xcount, ycount);
+        int[] yline = createLine(b, a, ycount, xcount);
+
+        // Correct lines
+        int i = xline.length;
+        while(xline[--i] > xcount) {
+            xline[i] = xcount;
+        }
+
+        i = yline.length;
+        while(yline[--i] > ycount) {
+            yline[i] = ycount;
+        }
+
+        if (Math.abs(angleExtent) >= 360) {
+            // Rasterize CIRCLE
+            addX0Line(mra, xline, cx2, cy2, b);
+            addX1Line(mra, xline, cx2, cy1, b);
+            addX2Line(mra, xline, cx1, cy1, b);
+            addX3Line(mra, xline, cx1, cy2, b);
+            addY0Line(mra, yline, cx2, cy2, a);
+            addY1Line(mra, yline, cx1, cy2, a);
+            addY2Line(mra, yline, cx1, cy1, a);
+            addY3Line(mra, yline, cx2, cy1, a);
+        } else {
+            // Rasterize ARC
+            angleStart = getNormAngle(angleStart);
+            double angleFinish = getNormAngle(angleStart + angleExtent);
+
+            if (angleExtent < 0) {
+                double tmp = angleStart;
+                angleStart = angleFinish;
+                angleFinish = tmp;
+            }
+
+            double radStart = -Math.toRadians(angleStart);
+            double radFinish = -Math.toRadians(angleFinish);
+            int ax1 = (int)(a * Math.cos(radStart));
+            int ay1 = (int)(b * Math.sin(radStart));
+            int ax2 = (int)(a * Math.cos(radFinish));
+            int ay2 = (int)(b * Math.sin(radFinish));
+
+            int[] seg1 = getSegment1(angleStart, ax1, ay1, xcount, ycount);
+            int[] seg2 = getSegment2(angleFinish, ax2, ay2, xcount, ycount);
+
+            // Start and Finish located in the same quater
+            if (angleStart < angleFinish && seg1[0] == seg2[0]) {
+                if (seg1[0] % 2 == 0) {
+                    seg1[2] = seg2[2];
+                } else {
+                    seg1[1] = seg2[1];
+                }
+                addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg1);
+                return mra;
+            }
+
+            addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg1);
+            addSeg(mra, cx1, cy1, cx2, cy2, a, b, xline, yline, seg2);
+
+            int startSeg = (seg1[0] + 1) % 8;
+            int finishSeg = seg2[0];
+
+            while (startSeg != finishSeg) {
+                switch(startSeg) {
+                case 0:
+                    addY3Line(mra, yline, cx2, cy1, a);
+                    break;
+                case 1:
+                    addX1Line(mra, xline, cx2, cy1, b);
+                    break;
+                case 2:
+                    addX2Line(mra, xline, cx1, cy1, b);
+                    break;
+                case 3:
+                    addY2Line(mra, yline, cx1, cy1, a);
+                    break;
+                case 4:
+                    addY1Line(mra, yline, cx1, cy2, a);
+                    break;
+                case 5:
+                    addX3Line(mra, xline, cx1, cy2, b);
+                    break;
+                case 6:
+                    addX0Line(mra, xline, cx2, cy2, b);
+                    break;
+                case 7:
+                    addY0Line(mra, yline, cx2, cy2, a);
+                    break;
+                }
+                startSeg = (startSeg + 1) % 8;
+            }
+        }
+
+        if (clip != null) {
+            mra.intersect(clip);
+        }
+
+        return mra;
+    }
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaBlitter.java b/awt/org/apache/harmony/awt/gl/render/JavaBlitter.java
new file mode 100644
index 0000000..67e0a59
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/JavaBlitter.java
@@ -0,0 +1,611 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 18.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.XORComposite;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * Java implenetation of the Blitter interface. Using when we can't 
+ * draw images natively.
+ */
+public class JavaBlitter implements Blitter {
+
+    /**
+     * Instead of multiplication and division we are using values from
+     * Lookup tables.
+     */
+    static byte mulLUT[][]; // Lookup table for multiplication
+    static byte divLUT[][]; // Lookup table for division
+
+    static{
+        mulLUT = new byte[256][256];
+        for(int i = 0; i < 256; i++){
+            for(int j = 0; j < 256; j++){
+                mulLUT[i][j] = (byte)((float)(i * j)/255 + 0.5f);
+            }
+        }
+        divLUT = new byte[256][256];
+        for(int i = 1; i < 256; i++){
+            for(int j = 0; j < i; j++){
+                divLUT[i][j] = (byte)(((float)j / 255) / ((float)i/ 255) * 255 + 0.5f);
+            }
+            for(int j = i; j < 256; j++){
+                divLUT[i][j] = (byte)255;
+            }
+        }
+    }
+
+    final static int AlphaCompositeMode = 1;
+    final static int XORMode = 2;
+
+    final static JavaBlitter inst = new JavaBlitter();
+
+    public static JavaBlitter getInstance(){
+        return inst;
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            AffineTransform xform, Composite comp, Color bgcolor,
+            MultiRectArea clip) {
+
+        if(xform == null){
+            blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                    sysxform, comp, bgcolor, clip);
+        }else{
+            double scaleX = xform.getScaleX();
+            double scaleY = xform.getScaleY();
+            double scaledX = dstX / scaleX;
+            double scaledY = dstY / scaleY;
+            AffineTransform at = new AffineTransform();
+            at.setToTranslation(scaledX, scaledY);
+            xform.concatenate(at);
+            sysxform.concatenate(xform);
+            blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
+                    sysxform, comp, bgcolor, clip);
+        }
+
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            Composite comp, Color bgcolor, MultiRectArea clip) {
+
+        if(sysxform == null) {
+            sysxform = new AffineTransform();
+        }
+        int type = sysxform.getType();
+        switch(type){
+            case AffineTransform.TYPE_TRANSLATION:
+                dstX += sysxform.getTranslateX();
+                dstY += sysxform.getTranslateY();
+            case AffineTransform.TYPE_IDENTITY:
+                 blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
+                        width, height, comp, bgcolor, clip);
+                break;
+            default:
+                int srcW = srcSurf.getWidth();
+                int srcH = srcSurf.getHeight();
+
+                int w = srcX + width < srcW ? width : srcW - srcX;
+                int h = srcY + height < srcH ? height : srcH - srcY;
+
+                ColorModel srcCM = srcSurf.getColorModel();
+                Raster srcR = srcSurf.getRaster().createChild(srcX, srcY,
+                        w, h, 0, 0, null);
+
+                ColorModel dstCM = dstSurf.getColorModel();
+                WritableRaster dstR = dstSurf.getRaster();
+
+                transformedBlit(srcCM, srcR, 0, 0, dstCM, dstR, dstX, dstY, w, h,
+                        sysxform, comp, bgcolor, clip);
+
+        }
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+
+        javaBlt(srcX, srcY, srcSurf.getWidth(), srcSurf.getHeight(),
+                srcSurf.getColorModel(), srcSurf.getRaster(), dstX, dstY,
+                dstSurf.getWidth(), dstSurf.getHeight(),
+                dstSurf.getColorModel(), dstSurf.getRaster(),
+                width, height, comp, bgcolor, clip);
+
+    }
+    public void javaBlt(int srcX, int srcY, int srcW, int srcH,
+            ColorModel srcCM, Raster srcRast, int dstX, int dstY,
+            int dstW, int dstH, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, Composite comp, Color bgcolor,
+            MultiRectArea clip){
+
+        int srcX2 = srcW - 1;
+        int srcY2 = srcH - 1;
+        int dstX2 = dstW - 1;
+        int dstY2 = dstH - 1;
+
+        if(srcX < 0){
+            width += srcX;
+            srcX = 0;
+        }
+        if(srcY < 0){
+            height += srcY;
+            srcY = 0;
+        }
+
+        if(dstX < 0){
+            width += dstX;
+            srcX -= dstX;
+            dstX = 0;
+        }
+        if(dstY < 0){
+            height += dstY;
+            srcY -= dstY;
+            dstY = 0;
+        }
+
+        if(srcX > srcX2 || srcY > srcY2) {
+            return;
+        }
+        if(dstX > dstX2 || dstY > dstY2) {
+            return;
+        }
+
+        if(srcX + width > srcX2) {
+            width = srcX2 - srcX + 1;
+        }
+        if(srcY + height > srcY2) {
+            height = srcY2 - srcY + 1;
+        }
+        if(dstX + width > dstX2) {
+            width = dstX2 - dstX + 1;
+        }
+        if(dstY + height > dstY2) {
+            height = dstY2 - dstY + 1;
+        }
+
+        if(width <= 0 || height <= 0) {
+            return;
+        }
+
+        int clipRects[];
+        if(clip != null) {
+            clipRects = clip.rect;
+        } else {
+            clipRects = new int[]{5, 0, 0, dstW - 1, dstH - 1};
+        }
+
+        boolean isAlphaComp = false;
+        int rule = 0;
+        float alpha = 0;
+        boolean isXORComp = false;
+        Color xorcolor = null;
+        CompositeContext cont = null;
+
+        if(comp instanceof AlphaComposite){
+            isAlphaComp = true;
+            AlphaComposite ac = (AlphaComposite) comp;
+            rule = ac.getRule();
+            alpha = ac.getAlpha();
+        }else if(comp instanceof XORComposite){
+            isXORComp = true;
+            XORComposite xcomp = (XORComposite) comp;
+            xorcolor = xcomp.getXORColor();
+        }else{
+            cont = comp.createContext(srcCM, dstCM, null);
+        }
+
+        for(int i = 1; i < clipRects[0]; i += 4){
+            int _sx = srcX;
+            int _sy = srcY;
+
+            int _dx = dstX;
+            int _dy = dstY;
+
+            int _w = width;
+            int _h = height;
+
+            int cx = clipRects[i];          // Clipping left top X
+            int cy = clipRects[i + 1];      // Clipping left top Y
+            int cx2 = clipRects[i + 2];     // Clipping right bottom X
+            int cy2 = clipRects[i + 3];     // Clipping right bottom Y
+
+            if(_dx > cx2 || _dy > cy2 || dstX2 < cx || dstY2 < cy) {
+                continue;
+            }
+
+            if(cx > _dx){
+                int shx = cx - _dx;
+                _w -= shx;
+                _dx = cx;
+                _sx += shx;
+            }
+
+            if(cy > _dy){
+                int shy = cy - _dy;
+                _h -= shy;
+                _dy = cy;
+                _sy += shy;
+            }
+
+            if(_dx + _w > cx2 + 1){
+                _w = cx2 - _dx + 1;
+            }
+
+            if(_dy + _h > cy2 + 1){
+                _h = cy2 - _dy + 1;
+            }
+
+            if(_sx > srcX2 || _sy > srcY2) {
+                continue;
+            }
+
+            if(isAlphaComp){
+                alphaCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
+                        dstCM, dstRast, _w, _h, rule, alpha, bgcolor);
+            }else if(isXORComp){
+                xorCompose(_sx, _sy, srcCM, srcRast, _dx, _dy,
+                        dstCM, dstRast, _w, _h, xorcolor);
+            }else{
+                Raster sr = srcRast.createChild(_sx, _sy, _w, _h, 0, 0, null);
+                WritableRaster dr = dstRast.createWritableChild(_dx, _dy,
+                        _w, _h, 0, 0, null);
+                cont.compose(sr, dr, dr);
+            }
+        }
+    }
+
+    void alphaCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
+            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, int rule, float alpha, Color bgcolor){
+
+        Object srcPixel, dstPixel;
+        int srcConstAllpha = (int)(alpha * 255 + 0.5f);
+        int srcRGB, dstRGB = 0;
+
+        if(bgcolor != null){
+            dstRGB = bgcolor.getRGB();
+        }
+
+        for(int sy = srcY, dy = dstY, srcYMax = srcY + height; sy < srcYMax; sy++, dy++){
+            for(int sx = srcX, dx = dstX, srcXMax = srcX + width; sx < srcXMax; sx++, dx++){
+                srcPixel = srcRast.getDataElements(sx, sy, null);
+                srcRGB = srcCM.getRGB(srcPixel);
+                if(bgcolor == null){
+                    dstPixel = dstRast.getDataElements(dx, dy, null);
+                    dstRGB = dstCM.getRGB(dstPixel);
+                }
+
+                dstRGB = compose(srcRGB, srcCM.isAlphaPremultiplied(),
+                        dstRGB, dstCM.hasAlpha(), dstCM.isAlphaPremultiplied(),
+                        rule, srcConstAllpha);
+
+                dstPixel = dstCM.getDataElements(dstRGB, null);
+                dstRast.setDataElements(dx,dy,dstPixel);
+            }
+        }
+    }
+
+    void xorCompose(int srcX, int srcY, ColorModel srcCM, Raster srcRast,
+            int dstX, int dstY, ColorModel dstCM, WritableRaster dstRast,
+            int width, int height, Color xorcolor){
+
+        Object srcPixel, dstPixel;
+        int xorRGB = xorcolor.getRGB();
+        int srcRGB, dstRGB;
+
+        for(int sy = srcY, dy = dstY, srcYMax = srcY + height; sy < srcYMax; sy++, dy++){
+            for(int sx = srcX, dx = dstX, srcXMax = srcX + width; sx < srcXMax; sx++, dx++){
+                srcPixel = srcRast.getDataElements(sx, sy, null);
+                dstPixel = dstRast.getDataElements(dx, dy, null);
+
+                srcRGB = srcCM.getRGB(srcPixel);
+                dstRGB = dstCM.getRGB(dstPixel);
+                dstRGB = srcRGB ^ xorRGB ^ dstRGB;
+
+                dstRGB = 0xff000000 | dstRGB;
+                dstPixel = dstCM.getDataElements(dstRGB, dstPixel);
+                dstRast.setDataElements(dx,dy,dstPixel);
+
+            }
+        }
+
+    }
+
+    private void transformedBlit(ColorModel srcCM, Raster srcR, int srcX, int srcY,
+            ColorModel dstCM, WritableRaster dstR, int dstX, int dstY,
+            int width, int height, AffineTransform at, Composite comp,
+            Color bgcolor,MultiRectArea clip) {
+
+        Rectangle srcBounds = new Rectangle(width, height);
+        Rectangle dstBlitBounds = new Rectangle(dstX, dstY, srcR.getWidth(), srcR.getHeight());
+
+        Rectangle transSrcBounds = getBounds2D(at, srcBounds).getBounds();
+        Rectangle transDstBlitBounds = getBounds2D(at, dstBlitBounds).getBounds();
+
+        int translateX = transDstBlitBounds.x - transSrcBounds.x;
+        int translateY = transDstBlitBounds.y - transSrcBounds.y;
+
+        AffineTransform inv = null;
+        try {
+             inv = at.createInverse();
+        } catch (NoninvertibleTransformException e) {
+            return;
+        }
+
+        double[] m = new double[6];
+        inv.getMatrix(m);
+
+        int clipRects[];
+        if(clip != null) {
+            clipRects = clip.rect;
+        } else {
+            clipRects = new int[]{5, 0, 0, dstR.getWidth(), dstR.getHeight()};
+        }
+
+        int compType = 0;
+        int srcConstAlpha = 0;
+        int rule = 0;
+        int bgRGB = bgcolor == null ? 0 : bgcolor.getRGB();
+        int srcRGB = 0, dstRGB = 0;
+        Object srcVal = null, dstVal = null;
+        if(comp instanceof AlphaComposite){
+            compType = AlphaCompositeMode;
+            AlphaComposite ac = (AlphaComposite) comp;
+            rule = ac.getRule();
+            srcConstAlpha = (int)(ac.getAlpha() * 255 + 0.5f);
+        }else if(comp instanceof XORComposite){
+            compType = XORMode;
+            XORComposite xor = (XORComposite) comp;
+            bgRGB = xor.getXORColor().getRGB();
+        }
+
+        for(int i = 1; i < clipRects[0]; i += 4){
+            Rectangle dstBounds = new Rectangle(clipRects[i], clipRects[i + 1], 0, 0);
+            dstBounds.add(clipRects[i + 2] + 1, clipRects[i + 1]);
+            dstBounds.add(clipRects[i + 2] + 1, clipRects[i + 3] + 1);
+            dstBounds.add(clipRects[i], clipRects[i + 3] + 1);
+
+            Rectangle bounds = dstBounds.intersection(transDstBlitBounds);
+
+            int minSrcX = srcBounds.x;
+            int minSrcY = srcBounds.y;
+            int maxSrcX = minSrcX + srcBounds.width;
+            int maxSrcY = minSrcY + srcBounds.height;
+
+            int minX = bounds.x;
+            int minY = bounds.y;
+            int maxX = minX + bounds.width;
+            int maxY = minY + bounds.height;
+
+            int hx = (int)((m[0] * 256) + 0.5);
+            int hy = (int)((m[1] * 256) + 0.5);
+            int vx = (int)((m[2] * 256) + 0.5);
+            int vy = (int)((m[3] * 256) + 0.5);
+            int sx = (int)((m[4] + m[0] * (bounds.x - translateX) + m[2] * (bounds.y - translateY)) * 256 + 0.5);
+            int sy = (int)((m[5] + m[1] * (bounds.x - translateX) + m[3] * (bounds.y - translateY)) * 256 + 0.5);
+
+            vx -= hx * bounds.width;
+            vy -= hy * bounds.width;
+
+            for(int y = minY; y < maxY; y++) {
+                for(int x = minX; x < maxX; x++) {
+                    int px = sx >> 8;
+                    int py = sy >> 8;
+                    if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
+                        switch(compType){
+                            case AlphaCompositeMode:
+                                srcVal = srcR.getDataElements(px , py , null);
+                                srcRGB = srcCM.getRGB(srcVal);
+                                if(bgcolor != null){
+                                    dstRGB = bgRGB;
+                                }else{
+                                    dstVal = dstR.getDataElements(x, y, null);
+                                    dstRGB = dstCM.getRGB(dstVal);
+                                }
+                                dstRGB = compose(srcRGB, srcCM.isAlphaPremultiplied(),
+                                        dstRGB, dstCM.hasAlpha(), dstCM.isAlphaPremultiplied(),
+                                        rule, srcConstAlpha);
+                                dstVal = dstCM.getDataElements(dstRGB, null);
+                                dstR.setDataElements(x, y, dstVal);
+                                break;
+
+                            case XORMode:
+                                srcVal = srcR.getDataElements(px , py , null);
+                                srcRGB = srcCM.getRGB(srcVal);
+                                dstVal = dstR.getDataElements(x, y, null);
+                                dstRGB = dstCM.getRGB(dstVal);
+                                dstRGB = srcRGB ^ bgRGB;
+
+                                dstRGB = 0xff000000 | dstRGB;
+                                dstVal = dstCM.getDataElements(dstRGB, null);
+                                dstR.setDataElements(x, y, dstVal);
+                                break;
+
+                            default:
+                                // awt.37=Unknown  composite type {0}
+                                throw new IllegalArgumentException(Messages.getString("awt.37", //$NON-NLS-1$
+                                        comp.getClass()));
+                        }
+                    }
+                    sx += hx;
+                    sy += hy;
+                }
+                sx += vx;
+                sy += vy;
+            }
+        }
+
+    }
+
+    private Rectangle2D getBounds2D(AffineTransform at, Rectangle r) {
+        int x = r.x;
+        int y = r.y;
+        int width = r.width;
+        int height = r.height;
+
+        float[] corners = {
+            x, y,
+            x + width, y,
+            x + width, y + height,
+            x, y + height
+        };
+
+        at.transform(corners, 0, corners, 0, 4);
+
+        Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0 , 0);
+        bounds.add(corners[2], corners[3]);
+        bounds.add(corners[4], corners[5]);
+        bounds.add(corners[6], corners[7]);
+
+        return bounds;
+    }
+
+    private int compose(int srcRGB, boolean isSrcAlphaPre,
+            int dstRGB, boolean dstHasAlpha, boolean isDstAlphaPre,
+            int rule, int srcConstAlpha){
+
+        int sa, sr, sg, sb, da, dr, dg, db;
+
+        sa = (srcRGB >> 24) & 0xff;
+        sr = (srcRGB >> 16) & 0xff;
+        sg = (srcRGB >> 8) & 0xff;
+        sb = srcRGB & 0xff;
+
+        if(isSrcAlphaPre){
+            sa = mulLUT[srcConstAlpha][sa] & 0xff;
+            sr = mulLUT[srcConstAlpha][sr] & 0xff;
+            sg = mulLUT[srcConstAlpha][sg] & 0xff;
+            sb = mulLUT[srcConstAlpha][sb] & 0xff;
+        }else{
+            sa = mulLUT[srcConstAlpha][sa] & 0xff;
+            sr = mulLUT[sa][sr] & 0xff;
+            sg = mulLUT[sa][sg] & 0xff;
+            sb = mulLUT[sa][sb] & 0xff;
+        }
+
+        da = (dstRGB >> 24) & 0xff;
+        dr = (dstRGB >> 16) & 0xff;
+        dg = (dstRGB >> 8) & 0xff;
+        db = dstRGB & 0xff;
+
+        if(!isDstAlphaPre){
+            dr = mulLUT[da][dr] & 0xff;
+            dg = mulLUT[da][dg] & 0xff;
+            db = mulLUT[da][db] & 0xff;
+        }
+
+        int Fs = 0;
+        int Fd = 0;
+        switch(rule){
+        case AlphaComposite.CLEAR:
+            break;
+
+        case AlphaComposite.DST:
+            Fd = 255;
+            break;
+
+        case AlphaComposite.DST_ATOP:
+            Fs = 255 - da;
+            Fd = sa;
+            break;
+
+        case AlphaComposite.DST_IN:
+            Fd = sa;
+            break;
+
+        case AlphaComposite.DST_OUT:
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.DST_OVER:
+            Fs = 255 - da;
+            Fd = 255;
+            break;
+
+        case AlphaComposite.SRC:
+            Fs = 255;
+            break;
+
+        case AlphaComposite.SRC_ATOP:
+            Fs = da;
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.SRC_IN:
+            Fs = da;
+            break;
+
+        case AlphaComposite.SRC_OUT:
+            Fs = 255 - da;
+            break;
+
+        case AlphaComposite.SRC_OVER:
+            Fs = 255;
+            Fd = 255 - sa;
+            break;
+
+        case AlphaComposite.XOR:
+            Fs = 255 - da;
+            Fd = 255 - sa;
+            break;
+        }
+        dr = (mulLUT[sr][Fs] & 0xff) + (mulLUT[dr][Fd] & 0xff);
+        dg = (mulLUT[sg][Fs] & 0xff) + (mulLUT[dg][Fd] & 0xff);
+        db = (mulLUT[sb][Fs] & 0xff) + (mulLUT[db][Fd] & 0xff);
+
+        da = (mulLUT[sa][Fs] & 0xff) + (mulLUT[da][Fd] & 0xff);
+
+        if(!isDstAlphaPre){
+            if(da != 255){
+                dr = divLUT[da][dr] & 0xff;
+                dg = divLUT[da][dg] & 0xff;
+                db = divLUT[da][db] & 0xff;
+            }
+        }
+        if(!dstHasAlpha) {
+            da = 0xff;
+        }
+        dstRGB = (da << 24) | (dr << 16) | (dg << 8) | db;
+
+        return dstRGB;
+
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaLineRasterizer.java b/awt/org/apache/harmony/awt/gl/render/JavaLineRasterizer.java
new file mode 100644
index 0000000..eb6f7b5
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/JavaLineRasterizer.java
@@ -0,0 +1,760 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.render;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+
+
+public class JavaLineRasterizer {
+
+    /**
+     *  LineDasher class provides dashing for particular dash style
+     */
+    public static class LineDasher {
+
+        int index;
+        float pos;
+        float phase;
+        float dash[];
+        float inv[];
+        boolean visible;
+
+        public LineDasher() {
+        }
+
+        public LineDasher(float dash[], float phase) {
+            this.dash = dash;
+            this.phase = phase;
+
+            inv = new float[dash.length];
+            int j = dash.length;
+            for (float element : dash) {
+                inv[--j] = element;
+            }
+            index = 0;
+            while (phase > dash[index]) {
+                phase -= dash[index];
+                index = (index + 1) % dash.length;
+            }
+            visible = index % 2 == 0;
+        }
+
+        void move(float step) { // main dasher
+            pos += step;
+            step += phase;
+            while(step >= dash[index]) {
+                step -= dash[index];
+                index = (index + 1) % dash.length;
+                visible = !visible;
+            }
+            phase = step;
+        }
+
+        float nextDash() {
+            phase = 0.0f;
+            index = (index + 1) % dash.length;
+            visible = !visible;
+            return dash[index];
+        }
+
+        LineDasher createDiagonal(double k, float length, boolean invert) {
+            LineDasher local = new LineDasher();
+            local.dash = new float[dash.length];
+            if (invert) { // inverted dasher
+                move(length);
+                local.phase = (float)((dash[index] - phase) * k);
+                local.visible = visible;
+                local.index = inv.length - index - 1;
+                for(int i = 0; i < inv.length; i++) {
+                    local.dash[i] = (float)(inv[i] * k);
+                }
+            } else {
+                local.phase = (float)(phase * k);
+                local.visible = visible;
+                local.index = index;
+                for(int i = 0; i < dash.length; i++) {
+                    local.dash[i] = (float)(dash[i] * k);
+                }
+                move(length);
+            }
+            return local;
+        }
+
+        LineDasher createOrtogonal(float length, boolean invert) {
+            LineDasher local = new LineDasher();
+            local.dash = new float[dash.length];
+            if (invert) { // inverted dasher
+                move(length);
+                local.phase = dash[index] - phase;
+                local.visible = visible;
+                local.index = inv.length - index - 1;
+                local.dash = inv;
+            } else {
+                local.phase = phase;
+                local.visible = visible;
+                local.index = index;
+                local.dash = dash;
+                move(length);
+            }
+            return local;
+        }
+
+        LineDasher createChild(float start) {
+            LineDasher child = new LineDasher();
+            child.phase = phase;
+            child.visible = visible;
+            child.index = index;
+            child.dash = dash;
+            child.move(start);
+            return child;
+        }
+
+    }
+
+    /**
+     * Line class provides rasterization for different line types
+     */
+    abstract static class Line {
+
+        int x1, y1, x2, y2;
+        int x, y;
+        MultiRectArea dst;
+
+        Line(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+            this.x1 = x1;
+            this.y1 = y1;
+            this.x2 = x2;
+            this.y2 = y2;
+            this.dst = dst;
+        }
+
+        static abstract class Diag extends Line {
+            int dx, dy, adx, ady, sx, sy;
+            int eBase, ePos, eNeg;
+            int xcount;
+            int e;
+
+            Diag(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                super(x1, y1, x2, y2, dst);
+                dx = x2 - x1;
+                dy = y2 - y1;
+                sy = 1;
+                if (dx > 0) {
+                    adx = dx;
+                    sx = 1;
+                } else {
+                    adx = -dx;
+                    sx = -1;
+                }
+                ady = dy;
+            }
+
+            float getLength() {
+                return (float)Math.sqrt(dx * dx + dy * dy);
+            }
+
+            static class Hor extends Diag {
+
+                Hor(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                    super(x1, y1, x2, y2, dst);
+                    eBase = ady + ady - adx;
+                    ePos = 2 * (ady - adx);
+                    eNeg = ady + ady;
+                    xcount = adx;
+                }
+
+                @Override
+                void rasterize() {
+                    e = eBase;
+                    x = x1;
+                    y = y1;
+                    rasterize(xcount);
+                }
+
+                @Override
+                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
+                    e = eBase + 2 * (ady * Math.abs(nx1 - x1) - adx * Math.abs(ny1 - y1));
+                    x = nx1;
+                    y = ny1;
+                    rasterize(dx > 0 ? nx2 - nx1 : nx1 - nx2);
+                }
+
+                @Override
+                void rasterize(int count) {
+                    int px = x;
+                    while (count-- > 0) {
+                        if (e >= 0) {
+                            if (sx > 0) {
+                                dst.addRect(px, y, x, y);
+                            } else {
+                                dst.addRect(x, y, px, y);
+                            }
+                            x += sx;
+                            y += sy;
+                            e += ePos;
+                            px = x;
+                        } else {
+                            e += eNeg;
+                            x += sx;
+                        }
+                    }
+                    if (sx > 0) {
+                        dst.addRect(px, y, x, y);
+                    } else {
+                        dst.addRect(x, y, px, y);
+                    }
+                }
+
+                @Override
+                void skip(int count) {
+                    while (count-- > 0) {
+                        x += sx;
+                        if (e >= 0) {
+                            y += sy;
+                            e += ePos;
+                        } else {
+                            e += eNeg;
+                        }
+                    }
+                }
+
+            }
+
+            static class Ver extends Diag {
+
+                Ver(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                    super(x1, y1, x2, y2, dst);
+                    eBase = adx + adx - ady;
+                    ePos = 2 * (adx - ady);
+                    eNeg = adx + adx;
+                    xcount = ady;
+                }
+
+                @Override
+                void rasterize() {
+                    e = eBase;
+                    x = x1;
+                    y = y1;
+                    rasterize(xcount);
+                }
+
+                @Override
+                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
+                    e = eBase + 2 * (adx * Math.abs(ny1 - y1) - ady * Math.abs(nx1 - x1));
+                    x = nx1;
+                    y = ny1;
+                    rasterize(ny2 - ny1);
+                }
+
+                @Override
+                void rasterize(int count) {
+                    int py = y;
+                    while (count-- > 0) {
+                        if (e >= 0) {
+                            dst.addRect(x, py, x, y);
+                            x += sx;
+                            y += sy;
+                            e += ePos;
+                            py = y;
+                        } else {
+                            y += sy;
+                            e += eNeg;
+                        }
+                    }
+                    dst.addRect(x, py, x, y);
+                }
+
+                @Override
+                void skip(int count) {
+                    while (count-- > 0) {
+                        y += sy;
+                        if (e >= 0) {
+                            x += sx;
+                            e += ePos;
+                        } else {
+                            e += eNeg;
+                        }
+                    }
+                }
+
+            }
+
+            static class HorDashed extends Hor {
+
+                LineDasher local;
+
+                HorDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher, boolean invert) {
+                    super(x1, y1, x2, y2, dst);
+                    float length = getLength();
+                    local = dasher.createDiagonal(xcount / length, length, invert);
+                }
+
+                @Override
+                void rasterize() {
+                    e = eBase;
+                    x = x1;
+                    y = y1;
+                    rasterizeDash(xcount, local);
+                }
+
+                @Override
+                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
+                    e = eBase + 2 * (ady * Math.abs(nx1 - x1) - adx * Math.abs(ny1 - y1));
+                    x = nx1;
+                    y = ny1;
+                    rasterizeDash(Math.abs(nx2 - nx1), local.createChild(Math.abs(nx1 - x1)));
+                }
+
+            }
+
+            static class VerDashed extends Ver {
+
+                LineDasher local;
+
+                VerDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher, boolean invert) {
+                    super(x1, y1, x2, y2, dst);
+                    float length = getLength();
+                    local = dasher.createDiagonal(xcount / length, length, invert);
+                }
+
+                @Override
+                void rasterize() {
+                    e = eBase;
+                    x = x1;
+                    y = y1;
+                    rasterizeDash(xcount, local);
+                }
+
+                @Override
+                void rasterizeClipped(int nx1, int ny1, int nx2, int ny2) {
+                    e = eBase + 2 * (adx * Math.abs(ny1 - y1) - ady * Math.abs(nx1 - x1));
+                    x = nx1;
+                    y = ny1;
+                    rasterizeDash(ny2 - ny1, local.createChild(ny1 - y1));
+                }
+
+            }
+
+            @Override
+            void rasterize(int[] clip, int index) {
+                int cx1 = clip[index + 0];
+                int cy1 = clip[index + 1];
+                int cx2 = clip[index + 2] + 1;
+                int cy2 = clip[index + 3] + 1;
+
+                int code1 =
+                    (x1 < cx1 ? 1 : 0) | (x1 >= cx2 ? 2 : 0) |
+                    (y1 < cy1 ? 8 : 0) | (y1 >= cy2 ? 4 : 0);
+                int code2 =
+                    (x2 < cx1 ? 1 : 0) | (x2 >= cx2 ? 2 : 0) |
+                    (y2 < cy1 ? 8 : 0) | (y2 >= cy2 ? 4 : 0);
+
+                // Outside
+                if ((code1 & code2) != 0) {
+                    return;
+                }
+
+                // Inside
+                if (code1 == 0 && code2 == 0) {
+                    rasterize();
+                    return;
+                }
+
+                // Clip
+                int nx1 = x1;
+                int ny1 = y1;
+                int nx2 = x2;
+                int ny2 = y2;
+                // need to clip
+                cx1 -= x1; cx2 -= x1;
+                cy1 -= y1; cy2 -= y1;
+//                int d;
+                int newx1 = 0, newy1 = 0, newx2 = 0, newy2 = 0;
+                if (code1 != 0) {
+                    newx1 = Integer.MAX_VALUE;
+                    if ((code1 & 8) != 0) {
+                        // clip point 1 with top clip bound
+                        newy1 = cy1;
+                        newx1 = clipY(dx, dy, newy1, true);
+
+                    } else if ((code1 & 4) != 0) {
+                        // clip point 1 with bottom clip bound
+                        newy1 = cy2 - 1;
+                        newx1 = clipY(dx, dy, newy1, false);
+                    }
+                    if ((code1 & 1) != 0 && (cx1 > newx1 || newx1 == Integer.MAX_VALUE)) {
+                        // clip point 1 with left clip bound
+                        newx1 = cx1;
+                        newy1 = clipX(dx, dy, newx1, false);
+                    } else if ((code1 & 2) != 0 && (newx1 >= cx2 || newx1 == Integer.MAX_VALUE)) {
+                        // clip point 1 with right clip bound
+                        newx1 = cx2 - 1;
+                        newy1 = clipX(dx, dy, newx1, false);
+                    }
+                    if (newx1 < cx1 || newx1 >= cx2 || newy1 < cy1 || newy1 >= cy2) {
+                        return;
+                    }
+//                    d = 2 * (ady * Math.abs(newx1) - adx * Math.abs(newy1)) + 2 * ady - adx;
+                } else {
+//                    d = (ady << 1) - adx;
+                }
+
+                if (code2 != 0) {
+                    newx2=Integer.MAX_VALUE;
+                    if ((code2 & 8) != 0) {
+                        // clip point 2 with top clip bound
+                        newy2 = cy1;
+                        newx2 = clipY(dx, dy, newy2, true);
+                    } else if ((code2 & 4) != 0) {
+                        // clip point 2 with bottom clip bound
+                        newy2 = cy2 - 1;
+                        newx2 = clipY(dx, dy, newy2, false);
+                    }
+                    if ((code2 & 1) != 0 && (cx1 > newx2 || newx2 == Integer.MAX_VALUE)) {
+                        // clip point 2 with left clip bound
+                        newx2 = cx1;
+                        newy2 = clipX(dx, dy, newx2, false);
+                    } else if ((code2 & 2) != 0 && (newx2 >= cx2 || newx2 == Integer.MAX_VALUE)) {
+                        // clip point 2 with right clip bound
+                        newx2 = cx2 - 1;
+                        newy2 = clipX(dx, dy, newx2, false);
+                    }
+                    if (newx2 < cx1 || newx2 >= cx2 || newy2 < cy1 || newy2 >= cy2) {
+                        return;
+                    }
+                    nx2 = x1 + newx2;
+                    ny2 = y1 + newy2;
+                }
+                nx1 = x1 + newx1;
+                ny1 = y1 + newy1;
+
+                rasterizeClipped(nx1, ny1, nx2, ny2);
+            }
+
+            abstract void rasterizeClipped(int nx1, int ny1, int nx2, int ny2);
+
+        }
+
+        static abstract class Ortog extends Line {
+
+            Ortog(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                super(x1, y1, x2, y2, dst);
+            }
+
+            static class Hor extends Ortog {
+
+                int dx;
+
+                Hor(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                    super(x1, y1, x2, y2, dst);
+                    dx = x2 - x1;
+                }
+
+                @Override
+                void rasterize() {
+                    if (dx > 0) {
+                        dst.addRect(x1, y1, x2, y2);
+                    } else {
+                        dst.addRect(x2, y2, x1, y1);
+                    }
+                }
+
+                @Override
+                void rasterize(int step) {
+                    int px = x;
+                    if (dx > 0) {
+                        x += step;
+                        dst.addRect(px, y1, x - 1, y2);
+                    } else {
+                        x -= step;
+                        dst.addRect(x + 1, y2, px, y1);
+                    }
+                }
+
+                @Override
+                void skip(int step) {
+                    if (dx > 0) {
+                        x += step;
+                    } else {
+                        x -= step;
+                    }
+                }
+
+                void rasterizeClipped(int nx1, int nx2) {
+                    if (nx1 < nx2) {
+                        dst.addRect(nx1, y1, nx2, y1);
+                    } else {
+                        dst.addRect(nx2, y1, nx1, y1);
+                    }
+                }
+
+                @Override
+                void rasterize(int[] clip, int index) {
+                    if (y1 >= clip[index + 1] && y1 <= clip[index + 3]) {
+                        int cx1 = clip[index + 0];
+                        int cx2 = clip[index + 2];
+                        if (x1 <= cx2 && x2 >= cx1) {
+                            int nx1, nx2;
+                            if (dx > 0) {
+                                nx1 = Math.max(x1, cx1);
+                                nx2 = Math.min(x2, cx2);
+                            } else {
+                                nx2 = Math.max(x2, cx1);
+                                nx1 = Math.min(x1, cx2);
+                            }
+                            rasterizeClipped(nx1, nx2);
+                        }
+                    }
+                }
+
+            }
+
+            static class Ver extends Ortog {
+
+                int dy;
+
+                Ver(int x1, int y1, int x2, int y2, MultiRectArea dst) {
+                    super(x1, y1, x2, y2, dst);
+                    dy = y2 - y1;
+                }
+
+                @Override
+                void rasterize() {
+                    dst.addRect(x1, y1, x2, y2);
+                }
+
+                @Override
+                void rasterize(int step) {
+                    int py = y;
+                    y += step;
+                    dst.addRect(x1, py, x2, y - 1);
+                }
+
+                @Override
+                void skip(int step) {
+                    y += step;
+                }
+
+                void rasterizeClipped(int ny1, int ny2) {
+                    dst.addRect(x1, ny1, x1, ny2);
+                }
+
+                @Override
+                void rasterize(int[] clip, int index) {
+                    if (x1 >= clip[index] && x1 <= clip[index + 2]) {
+                        int cy1 = clip[index + 1];
+                        int cy2 = clip[index + 3];
+                        if (y1 <= cy2 && y2 >= cy1) {
+                            rasterizeClipped(Math.max(y1, cy1), Math.min(y2, cy2));
+                        }
+                    }
+                }
+
+            }
+
+            static class HorDashed extends Hor {
+
+                LineDasher local;
+
+                HorDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher) {
+                    super(x1, y1, x2, y2, dst);
+                    dx = x2 - x1;
+                    local = dasher.createOrtogonal(Math.abs(dx), false);
+                }
+
+                @Override
+                void rasterize() {
+                    x = x1;
+                    y = y1;
+                    rasterizeDash(Math.abs(dx), local);
+                }
+
+                @Override
+                void rasterizeClipped(int nx1, int nx2) {
+                    x = nx1;
+                    y = y1;
+                    rasterizeDash(Math.abs(nx2 - nx1), local.createChild(Math.abs(nx1 - x1)));
+                }
+
+            }
+
+            static class VerDashed extends Ver {
+
+                LineDasher local;
+
+                VerDashed(int x1, int y1, int x2, int y2, MultiRectArea dst, LineDasher dasher, boolean invert) {
+                    super(x1, y1, x2, y2, dst);
+                    dy = y2 - y1;
+                    local = dasher.createOrtogonal(dy, invert);
+                }
+
+                @Override
+                void rasterize() {
+                    x = x1;
+                    y = y1;
+                    rasterizeDash(dy, local);
+                }
+
+                @Override
+                void rasterizeClipped(int ny1, int ny2) {
+                    x = x1;
+                    y = ny1;
+                    rasterizeDash(ny2 - ny1, local.createChild(ny1));
+                }
+
+            }
+
+        }
+
+        abstract void rasterize();
+        abstract void rasterize(int[] clip, int index);
+        abstract void rasterize(int count);
+        abstract void skip(int count);
+
+        void rasterizeDash(int count, LineDasher dasher) {
+            float delta = dasher.dash[dasher.index] - dasher.phase;
+            int step = (int)delta;
+            delta -= step;
+            while(count > step) {
+                if (dasher.visible) {
+                    rasterize(step);
+                } else {
+                    skip(step);
+                }
+                count -= step;
+                delta += dasher.nextDash();
+                step = (int)delta;
+                delta -= step;
+            }
+            if (count > 0 && dasher.visible) {
+                rasterize(count);
+                dasher.move(count);
+            }
+        }
+
+    }
+
+    /**
+     * Common clipping method
+     */
+    static int clip(int dX1, int dX2, int cX, boolean top) {
+        int adX1 = dX1 < 0 ? -dX1 : dX1;
+        int adX2 = dX2 < 0 ? -dX2 : dX2;
+        if (adX1 <= adX2) {
+            // obtuse intersection angle
+            return ((dX1 << 1) * cX + (dX1 > 0 ? dX2 : -dX2)) / (dX2 << 1);
+        }
+        int k;
+        if (top) {
+            k = -dX1 + (dX2 < 0 ? 0 : dX1 > 0 ? (dX2 << 1) : -(dX2 << 1));
+        } else {
+            k = dX1 + (dX2 > 0 ? 0 : dX1 > 0 ? (dX2 << 1) : -(dX2 << 1));
+        }
+
+        k += dX1 > 0 == dX2 > 0 ? -1 : 1;
+        return ((dX1 << 1) * cX + k) / (dX2 << 1);
+    }
+
+    /**
+     * Clipping along X axis
+     */
+    static int clipX(int dx, int dy, int cy, boolean top) {
+        return clip(dy, dx, cy, top);
+    }
+
+    /**
+     * Clipping along Y axis
+     */
+    static int clipY(int dx, int dy, int cx, boolean top) {
+        return clip(dx, dy, cx, top);
+    }
+
+    /**
+     * Rasterizes line using clippind and dashing style
+     * @param x1 - the x coordinate of the first control point
+     * @param y1 - the y coordinate of the first control point
+     * @param x2 - the x coordinate of the second control point
+     * @param y2 - the y coordinate of the second control point
+     * @param clip - the MultiRectArea object of clipping area
+     * @param dasher - the dasher style
+     * @param invert - the invert indicator, always false
+     * @return a MultiRectArea of rasterizer line
+     */
+    public static MultiRectArea rasterize(int x1, int y1, int x2, int y2, MultiRectArea clip, LineDasher dasher, boolean invert) {
+
+        MultiRectArea dst = new MultiRectArea(false);
+        int dx = x2 - x1;
+        int dy = y2 - y1;
+
+        // Point
+        if (dx == 0 && dy == 0) {
+            if ((clip == null || clip.contains(x1, y1)) && (dasher == null || dasher.visible)) {
+                dst = new MultiRectArea(x1, y1, x1, y1);
+            }
+            return dst;
+        }
+
+        if (dy < 0) {
+            return rasterize(x2, y2, x1, y1, clip, dasher, true);
+        }
+
+        Line line;
+        if (dasher == null) {
+            if (dx == 0) {
+                line = new Line.Ortog.Ver(x1, y1, x2, y2, dst);
+            } else
+                if (dy == 0) {
+                    line = new Line.Ortog.Hor(x1, y1, x2, y2, dst);
+                } else {
+                    if (dy < Math.abs(dx)) {
+                        line = new Line.Diag.Hor(x1, y1, x2, y2, dst);
+                    } else {
+                        line = new Line.Diag.Ver(x1, y1, x2, y2, dst);
+                    }
+                }
+        } else {
+            if (dx == 0) {
+                line = new Line.Ortog.VerDashed(x1, y1, x2, y2, dst, dasher, invert);
+            } else
+                if (dy == 0) {
+                    line = new Line.Ortog.HorDashed(x1, y1, x2, y2, dst, dasher);
+                } else {
+                    if (dy < Math.abs(dx)) {
+                        line = new Line.Diag.HorDashed(x1, y1, x2, y2, dst, dasher, invert);
+                    } else {
+                        line = new Line.Diag.VerDashed(x1, y1, x2, y2, dst, dasher, invert);
+                    }
+                }
+        }
+
+
+        if (clip == null || clip.isEmpty()) {
+            line.rasterize();
+        } else {
+            for(int i = 1; i < clip.rect[0]; i += 4) {
+                line.rasterize(clip.rect, i);
+            }
+        }
+
+        return dst;
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaShapeRasterizer.java b/awt/org/apache/harmony/awt/gl/render/JavaShapeRasterizer.java
new file mode 100644
index 0000000..dbaaf53
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/JavaShapeRasterizer.java
@@ -0,0 +1,475 @@
+/*
+ *  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 Denis M. Kishenko
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.Shape;
+import java.awt.geom.PathIterator;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public class JavaShapeRasterizer {
+
+    static final int POINT_CAPACITY = 16;
+
+    int edgesCount;
+    int edgeCur;
+    int[] edgesX;
+    int[] edgesY;
+    int[] edgesYS; // Y coordinate of edge START point
+    int[] edgesN;
+    int[] edgesDY;
+    int[] bounds;
+    int boundCount;
+    boolean[] edgesExt; // Extremal points
+
+    int activeCount;
+    float[] activeX;
+    int[] activeYEnd;
+    float[] activeXStep;
+    int[] activeDY;
+    boolean[] activeExt;
+
+    int[] crossX;
+    int[] crossDY;
+
+    Filler filler;
+
+    /**
+     * Rasterization filler for different path rules
+     */
+    static abstract class Filler {
+
+        static class NonZero extends Filler {
+            @Override
+            void add(MultiRectArea.LineCash rect, int[] points, int[] orient, int length, int y) {
+
+                int[] dst = new int[length];
+                int dstLength = 1;
+                dst[0] = points[0];
+                int count = 0;
+                boolean inside = true;
+                for(int i = 0; i < length; i++) {
+                    count += orient[i] > 0 ? 1 : -1;
+                    if (count == 0) {
+                        dst[dstLength++] = points[i];
+                        inside = false;
+                    } else {
+                        if (!inside) {
+                            dst[dstLength++] = points[i];
+                            inside = true;
+                        }
+                    }
+
+                }
+
+                for(int i = 1; i < dstLength; i += 2) {
+                    dst[i]--;
+                }
+
+                dstLength = excludeEmpty(dst, dstLength);
+//              System.out.println("test");
+
+                dstLength = union(dst, dstLength);
+
+                rect.addLine(dst, dstLength);
+            }
+        }
+
+        static class EvenOdd extends Filler {
+            @Override
+            void add(MultiRectArea.LineCash rect, int[] points, int[] orient, int length, int y) {
+    /*
+                int[] buf = new int[length];
+                int j = 0;
+                for(int i = 0; i < length - 1; i++) {
+                    if (points[i] != points[i + 1]) {
+                        buf[j++] = points[i];
+                    }
+                }
+    */
+                for(int i = 1; i < length; i += 2) {
+                    points[i]--;
+                }
+
+                length = excludeEmpty(points, length);
+//              System.out.println("test");
+
+                length = union(points, length);
+                rect.addLine(points, length);
+    /*
+                for(int i = 0; i < length;) {
+                    rect.add(points[i++], y, points[i++], y);
+                }
+    */
+            }
+        }
+
+        abstract void add(MultiRectArea.LineCash rect, int[] points, int[] orient, int length, int y);
+
+        static int excludeEmpty(int[] points, int length) {
+            int i = 0;
+            while(i < length) {
+                if (points[i] <= points[i + 1]) {
+                    i += 2;
+                } else {
+                    length -= 2;
+                    System.arraycopy(points, i + 2, points, i, length - i);
+                }
+            }
+            return length;
+        }
+
+        static int union(int[] points, int length) {
+            int i = 1;
+            while(i < length - 1) {
+                if (points[i] < points[i - 1]) {
+                    System.arraycopy(points, i + 1, points, i - 1, length - i - 1);
+                    length -= 2;
+                } else
+                if (points[i] >= points[i + 1] - 1) {
+                    System.arraycopy(points, i + 2, points, i, length - i - 2);
+                    length -= 2;
+                } else {
+                    i += 2;
+                }
+            }
+            return length;
+        }
+
+    }
+
+    public JavaShapeRasterizer() {
+    }
+
+    /**
+     * Checks buffer size and realloc if necessary
+     */
+    int[] checkBufSize(int[] buf, int size) {
+        if (size == buf.length) {
+            int[] tmp;
+            tmp = new int[size + POINT_CAPACITY];
+            System.arraycopy(buf, 0, tmp, 0, buf.length);
+            buf = tmp;
+        }
+        return buf;
+    }
+
+    /**
+     * Adds to the buffers new edge 
+     */
+    void addEdge(int x, int y, int num) {
+        edgesX = checkBufSize(edgesX, edgesCount);
+        edgesY = checkBufSize(edgesY, edgesCount);
+        edgesN = checkBufSize(edgesN, edgesCount);
+        edgesX[edgesCount] = x;
+        edgesY[edgesCount] = y;
+        edgesN[edgesCount] = (num << 16) | edgesCount;
+        edgesCount++;
+    }
+
+    /**
+     * Prepare all buffers and variable to rasterize shape 
+     */
+    void makeBuffer(PathIterator path, double flatness) {
+        edgesX = new int[POINT_CAPACITY];
+        edgesY = new int[POINT_CAPACITY];
+        edgesN = new int[POINT_CAPACITY];
+        bounds = new int[POINT_CAPACITY];
+        boundCount = 0;
+        edgesCount = 0;
+
+        if (path.getWindingRule() == PathIterator.WIND_EVEN_ODD) {
+            filler = new Filler.EvenOdd();
+        } else {
+            filler = new Filler.NonZero();
+        }
+        float[] coords = new float[2];
+        boolean closed = true;
+        while (!path.isDone()) {
+            switch(path.currentSegment(coords)) {
+            case PathIterator.SEG_MOVETO:
+                if (!closed) {
+                    boundCount++;
+                    bounds = checkBufSize(bounds, boundCount);
+                    bounds[boundCount] = edgesCount;
+                }
+                addEdge((int)coords[0], (int)coords[1], boundCount);
+                closed = false;
+                break;
+            case PathIterator.SEG_LINETO:
+                addEdge((int)coords[0], (int)coords[1], boundCount);
+                break;
+            case PathIterator.SEG_CLOSE:
+                boundCount++;
+                bounds = checkBufSize(bounds, boundCount);
+                bounds[boundCount] = edgesCount;
+                closed = true;
+                break;
+            default:
+                // awt.36=Wrong segment
+                throw new RuntimeException(Messages.getString("awt.36")); //$NON-NLS-1$
+            }
+            path.next();
+        }
+        if (!closed) {
+            boundCount++;
+            bounds = checkBufSize(bounds, boundCount);
+            bounds[boundCount] = edgesCount;
+        }
+    }
+
+    /**
+     * Sort buffers
+     */
+    void sort(int[] master, int[] slave, int length) {
+        for(int i = 0; i < length - 1; i++) {
+            int num = i;
+            int min = master[num];
+            for(int j = i + 1; j < length; j++) {
+                if (master[j] < min) {
+                    num = j;
+                    min = master[num];
+                }
+            }
+            if (num != i) {
+                master[num] = master[i];
+                master[i] = min;
+                min = slave[num];
+                slave[num] = slave[i];
+                slave[i] = min;
+            }
+        }
+    }
+
+    int getNext(int cur) {
+        int n = edgesN[cur];
+        int bound = n >> 16;
+        int num = (n & 0xFFFF) + 1;
+        if (num == bounds[bound + 1]) {
+            return bounds[bound];
+        }
+        return num;
+    }
+
+    int getPrev(int cur) {
+        int n = edgesN[cur];
+        int bound = n >> 16;
+        int num = (n & 0xFFFF) - 1;
+        if (num < bounds[bound]) {
+            return bounds[bound + 1] - 1;
+        }
+        return num;
+    }
+
+    int getNextShape(int cur) {
+        int bound = edgesN[cur] >> 16;
+        return bounds[bound + 1];
+    }
+
+    void init() {
+
+        edgesYS = new int[edgesCount];
+        System.arraycopy(edgesY, 0, edgesYS, 0, edgesCount);
+        // Create edgesDY
+        edgesDY = new int[edgesCount];
+        for(int i = 0; i < edgesCount; i++) {
+            int dy = edgesY[getNext(i)] - edgesY[i];
+            edgesDY[i] = dy;
+        }
+
+        // Create edgesExt
+        edgesExt = new boolean[edgesCount];
+        int prev = -1;
+        int i = 0;
+        int pos = 0;
+        while(i < edgesCount) {
+
+            TOP: {
+                do {
+                    if (edgesDY[i] > 0) {
+                        break TOP;
+                    }
+                    i = getNext(i);
+                } while (i != pos);
+                i = pos = getNextShape(i);
+                continue;
+            }
+
+            BOTTOM: {
+                do {
+                    if (edgesDY[i] < 0) {
+                        break BOTTOM;
+                    }
+                    if (edgesDY[i] > 0) {
+                        prev = i;
+                    }
+                    i = getNext(i);
+                } while (i != pos);
+                i = pos = getNextShape(i);
+                continue;
+            }
+
+            if (prev != -1) {
+                edgesExt[prev] = true;
+            }
+            edgesExt[i] = true;
+        }
+
+        // Sort edgesY and edgesN
+        sort(edgesYS, edgesN, edgesCount);
+
+        edgeCur = 0;
+        activeCount = 0;
+        activeX = new float[edgesCount];
+        activeYEnd = new int[edgesCount];
+        activeXStep = new float[edgesCount];
+        activeDY = new int[edgesCount];
+        activeExt = new boolean[edgesCount];
+
+        crossX = new int[edgesCount];
+        crossDY = new int[edgesCount];
+    }
+
+    /**
+     * Marks edge as active
+     */
+    void addActiveEdge(int levelY, int start, int end, boolean back) {
+        int dy = back ? -edgesDY[end] : edgesDY[start];
+        if (dy <= 0) {
+            return;
+        }
+        int x1 = edgesX[start];
+        int dx = edgesX[end] - x1;
+        activeX[activeCount] = x1;
+        activeYEnd[activeCount] = edgesY[end];
+        activeXStep[activeCount] = dx / (float)dy;
+        activeDY[activeCount] = back ? -dy : dy;
+        activeExt[activeCount] = back ? edgesExt[end] : edgesExt[start];
+        activeCount++;
+    }
+
+    /**
+     * Find new active edges
+     */
+    int findActiveEdges(int levelY) {
+
+        int edgeActive = edgeCur;
+        while (edgeActive < edgesCount && edgesYS[edgeActive] == levelY) {
+            edgeActive++;
+        }
+
+        int activeNext = edgeActive;
+
+        while (edgeActive > edgeCur) {
+            edgeActive--;
+            int num = edgesN[edgeActive] & 0xFFFF;
+            addActiveEdge(levelY, num, getPrev(edgeActive), true);
+            addActiveEdge(levelY, num, getNext(edgeActive), false);
+        }
+
+        edgeCur = activeNext;
+
+        if (activeNext == edgesCount) {
+            return edgesY[edgesCount - 1];
+        }
+        return edgesYS[activeNext];
+    }
+
+    /**
+     * Rasterizes shape with particular flatness
+     * @param shape - the souze Shape to be rasterized
+     * @param flatness - the rasterization flatness
+     * @return a MultiRectArea of rasterized shape
+     */
+    public MultiRectArea rasterize(Shape shape, double flatness) {
+
+        PathIterator path = shape.getPathIterator(null, flatness);
+
+        // Shape is empty
+        if (path.isDone()) {
+            return new MultiRectArea();
+        }
+
+        makeBuffer(path, flatness);
+
+        init();
+
+        int y = edgesYS[0];
+        int nextY = y;
+        int crossCount;
+
+        MultiRectArea.LineCash rect = new MultiRectArea.LineCash(edgesCount);
+        rect.setLine(y);
+
+        while(y <= nextY) {
+
+            crossCount = 0;
+
+            if (y == nextY) {
+
+                int i = activeCount;
+                while(i > 0) {
+                    i--;
+                    if (activeYEnd[i] == y) {
+
+                        activeCount--;
+                        int length = activeCount - i;
+                        if (length != 0) {
+                            int pos = i + 1;
+                            System.arraycopy(activeX, pos, activeX, i, length);
+                            System.arraycopy(activeYEnd, pos, activeYEnd, i, length);
+                            System.arraycopy(activeXStep, pos, activeXStep, i, length);
+                            System.arraycopy(activeDY, pos, activeDY, i, length);
+                            System.arraycopy(activeExt, pos, activeExt, i, length);
+                        }
+                    }
+                }
+
+                nextY = findActiveEdges(y);
+            }
+
+            // Get X crossings
+            for(int i = 0; i < activeCount; i++) {
+                crossX[crossCount] = (int)Math.ceil(activeX[i]);
+                crossDY[crossCount] = activeDY[i];
+                crossCount++;
+            }
+
+            if (crossCount == 0) {
+                rect.skipLine();
+            } else {
+                // Sort X crossings
+                sort(crossX, crossDY, crossCount);
+                filler.add(rect, crossX, crossDY, crossCount, y);
+            }
+
+            for(int i = 0; i < activeCount; i++) {
+                activeX[i] += activeXStep[i];
+            }
+
+            y++;
+        }
+
+        return rect;
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java b/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java
new file mode 100644
index 0000000..322ba57
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java
@@ -0,0 +1,263 @@
+/*
+ *  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 Ilya S. Okomin
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.*;
+import java.awt.image.*;
+
+
+import java.awt.font.GlyphMetrics;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+
+import org.apache.harmony.awt.gl.TextRenderer;
+import org.apache.harmony.awt.gl.font.CommonGlyphVector;
+import org.apache.harmony.awt.gl.font.FontPeerImpl;
+import org.apache.harmony.awt.gl.font.Glyph;
+import org.apache.harmony.awt.gl.image.BufferedImageGraphics2D;
+
+public class JavaTextRenderer extends TextRenderer {
+
+    public static final JavaTextRenderer inst = new JavaTextRenderer();
+
+    @Override
+    public void drawGlyphVector(Graphics2D g, GlyphVector glyphVector,
+            float x, float y) {
+
+        AffineTransform at = g.getTransform();
+        Rectangle c = g.getClipBounds();
+        if (at != null){
+            int atType = at.getType();
+            if (atType == AffineTransform.TYPE_TRANSLATION) {
+                c.translate((int)Math.round(at.getTranslateX()), (int)Math.round(at.getTranslateY()));
+            }
+        }
+
+        WritableRaster wr = ((BufferedImageGraphics2D)g).getWritableRaster();
+        ColorModel cm = ((BufferedImageGraphics2D)g).getColorModel();
+
+        Rectangle rBounds = wr.getBounds();
+
+        Object color = cm.getDataElements(g.getColor().getRGB(), null);
+
+        drawClipGlyphVector(wr, color, glyphVector, (int)Math.round(x + at.getTranslateX()), (int)Math.round(y + at.getTranslateY()),
+        Math.max(c.x,rBounds.x),
+        Math.max(c.y,rBounds.y),
+        Math.min((int)Math.round(c.getMaxX()), (int)Math.round(rBounds.getMaxX())),
+        Math.min((int)Math.round(c.getMaxY()), (int)Math.round(rBounds.getMaxY())));
+
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void drawString(Graphics2D g, String str, float x, float y) {
+        AffineTransform at = g.getTransform();
+        Rectangle c = g.getClipBounds();
+        if (at != null){
+            int atType = at.getType();
+            if (atType == AffineTransform.TYPE_TRANSLATION) {
+                c.translate((int)Math.round(at.getTranslateX()), (int)Math.round(at.getTranslateY()));
+            }
+        }
+        WritableRaster wr = ((BufferedImageGraphics2D)g).getWritableRaster();
+        ColorModel cm = ((BufferedImageGraphics2D)g).getColorModel();
+        Rectangle rBounds = wr.getBounds();
+
+        Object color = cm.getDataElements(g.getColor().getRGB(), null);
+
+        drawClipString(wr, color, str, (FontPeerImpl) (g.getFont().getPeer()),
+                (int)Math.round(x + at.getTranslateX()), (int)Math.round(y + at.getTranslateY()),
+                Math.max(c.x,rBounds.x),
+                Math.max(c.y,rBounds.y),
+                Math.min((int)Math.round(c.getMaxX()), (int)Math.round(rBounds.getMaxX())),
+                Math.min((int)Math.round(c.getMaxY()), (int)Math.round(rBounds.getMaxY())));
+
+    }
+
+    /**
+     * 
+     * Draws string on specified raster at desired position.
+     *  
+     * @param raster specified WritableRaster to draw at
+     * @param color color of the text
+     * @param glyphVector GlyphVector object to draw
+     * @param x start X position to draw
+     * @param y start Y position to draw
+     * @param cMinX minimum x of the raster area to draw
+     * @param cMinY minimum y of the raster area to draw
+     * @param cMaxX maximum x of the raster area to draw
+     * @param cMaxY maximum y of the raster area to draw
+     */
+    public void drawClipGlyphVector(WritableRaster raster, Object color,
+            GlyphVector glyphVector, int x, int y,
+            int cMinX, int cMinY, int cMaxX, int cMaxY) {
+        // TODO: implement complex clipping
+
+        int xSrcSurf, ySrcSurf; // Start point in String rectangle
+        int xDstSurf, yDstSurf; // Start point in Surface rectangle
+        int clWidth, clHeight;
+
+        for (int i = 0; i < glyphVector.getNumGlyphs(); i++) {
+            Glyph gl = ((CommonGlyphVector) glyphVector).vector[i];
+
+            if (gl.getPointWidth() == 0) {
+                continue;
+            }
+
+            byte[] data = gl.getBitmap();
+            if (data != null) {
+                Point2D pos = glyphVector.getGlyphPosition(i);
+
+                xSrcSurf = 0;//gl.bmp_left;
+                ySrcSurf = 0;//gl.bmp_rows - gl.bmp_top;
+
+                xDstSurf = x + (int)pos.getX() + (int) gl.getGlyphPointMetrics().getLSB();// + gl.bmp_left;
+                yDstSurf = y - gl.bmp_top/*getPointHeight()*/  + (int) pos.getY();// - (gl.bmp_rows-gl.bmp_top);
+
+                int textWidth = gl.bmp_width;
+                int textHeight = gl.getPointHeight();
+
+                // if Regions don't intersect
+                if ((xDstSurf > cMaxX) || (yDstSurf > cMaxY) || (xDstSurf + textWidth < cMinX)
+                        || (yDstSurf + textHeight < cMinY)) {
+                    // Nothing to do
+                } else {
+                    if (xDstSurf >= cMinX) {
+                        clWidth = Math.min(textWidth, cMaxX - xDstSurf);
+                    } else {
+                        xSrcSurf += cMinX - xDstSurf;
+                        clWidth = Math.min(cMaxX - cMinX, textWidth - (cMinX - xDstSurf));
+                        xDstSurf = cMinX;
+                    }
+                    if (yDstSurf >= cMinY) {
+                        clHeight = Math.min(textHeight, cMaxY - yDstSurf);
+                    } else {
+                        ySrcSurf += cMinY - yDstSurf;
+                        clHeight = Math.min(cMaxY - cMinY, textHeight - (cMinY - yDstSurf));
+                        yDstSurf = cMinY;
+                    }
+                    //     Drawing on the Raster
+                    for (int h=0; h<clHeight; h++){
+                        for (int w=0; w < clWidth ; w++) {
+                            byte currByte = data[(ySrcSurf + h)*gl.bmp_pitch + (xSrcSurf+w)/8];
+                            boolean emptyByte = ((currByte & (1 << (7 - ((xSrcSurf+w) % 8)))) != 0);
+                            if (emptyByte) {
+                                raster.setDataElements(xDstSurf+w, yDstSurf+h, color);
+                            } else {
+                                // Nothing to do
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    /**
+     * Draws string on specified raster at desired position.
+     *  
+     * @param raster specified WritableRaster to draw at
+     * @param color color of the text
+     * @param str text to draw
+     * @param font font peer to use for drawing text
+     * @param x start X position to draw
+     * @param y start Y position to draw
+     * @param cMinX minimum x of the raster area to draw
+     * @param cMinY minimum y of the raster area to draw
+     * @param cMaxX maximum x of the raster area to draw
+     * @param cMaxY maximum y of the raster area to draw
+     */    
+    public void drawClipString(WritableRaster raster, Object color, String str,
+            FontPeerImpl font, int x, int y, int cMinX, int cMinY, int cMaxX,
+            int cMaxY) {
+        // TODO: implement complex clipping
+
+        int xSrcSurf, ySrcSurf; // Start point in String rectangle
+        int xDstSurf, yDstSurf; // Start point in Surface rectangle
+        int clWidth, clHeight;
+
+        char[] chars = str.toCharArray();
+
+        int xBaseLine = x;
+        int yBaseLine = y;
+
+        for (char element : chars) {
+            Glyph gl = font.getGlyph(element);
+            GlyphMetrics pointMetrics = gl.getGlyphPointMetrics();
+            if (gl.getWidth() == 0) {
+                xBaseLine += pointMetrics.getAdvanceX();
+                continue;
+            }
+
+            byte[] data = gl.getBitmap();
+            if (data == null) {
+                xBaseLine += pointMetrics.getAdvanceX();
+            } else {
+
+                xSrcSurf = 0;
+                ySrcSurf = 0;
+
+                xDstSurf = Math.round(xBaseLine + gl.getGlyphPointMetrics().getLSB());
+                yDstSurf = yBaseLine - gl.bmp_top;
+
+                int textWidth = gl.bmp_width;
+                int textHeight = gl.getPointHeight();
+
+                // if Regions don't intersect
+                if ((xDstSurf > cMaxX) || (yDstSurf > cMaxY) || (xDstSurf + textWidth < cMinX)
+                        || (yDstSurf + textHeight < cMinY)) {
+                    // Nothing to do
+                } else {
+                    if (xDstSurf >= cMinX) {
+                        clWidth = Math.min(textWidth, cMaxX - xDstSurf);
+                    } else {
+                        xSrcSurf += cMinX - xDstSurf;
+                        clWidth = Math.min(cMaxX - cMinX, textWidth - (cMinX - xDstSurf));
+                        xDstSurf = cMinX;
+                    }
+                    if (yDstSurf >= cMinY) {
+                        clHeight = Math.min(textHeight, cMaxY - yDstSurf);
+                    } else {
+                        ySrcSurf += cMinY - yDstSurf;
+                        clHeight = Math.min(cMaxY - cMinY, textHeight - (cMinY - yDstSurf));
+                        yDstSurf = cMinY;
+                    }
+
+                    // Drawing on the Raster
+                    for (int h=0; h<clHeight; h++){
+                        for (int w=0; w < clWidth ; w++) {
+                            byte currByte = data[(ySrcSurf + h)*gl.bmp_pitch + (xSrcSurf+w)/8];
+                            boolean emptyByte = ((currByte & (1 << (7 - ((xSrcSurf+w) % 8)))) != 0);
+                            if (emptyByte) {
+                                raster.setDataElements(xDstSurf+w, yDstSurf+h, color);
+                            } else {
+                                // Nothing to do
+                            }
+                        }
+                    }
+                }
+                xBaseLine += pointMetrics.getAdvanceX();
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/gl/render/NativeImageBlitter.java b/awt/org/apache/harmony/awt/gl/render/NativeImageBlitter.java
new file mode 100644
index 0000000..b0ebc97
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/NativeImageBlitter.java
@@ -0,0 +1,218 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 26.11.2005
+ *
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+
+import org.apache.harmony.awt.gl.ImageSurface;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+import org.apache.harmony.awt.gl.XORComposite;
+
+/**
+ * This kind of blitters is intended for drawing one image on the buffered
+ * or volatile image. For the moment we can blit natively Buffered Images which 
+ * have sRGB, Linear_RGB, Linear_Gray Color Space and type different 
+ * from BufferedImage.TYPE_CUSTOM, Volatile Images and Images which received 
+ * using Toolkit and Component classes.
+ */
+public class NativeImageBlitter implements Blitter {
+
+
+    final static NativeImageBlitter inst = new NativeImageBlitter();
+
+    public static NativeImageBlitter getInstance(){
+        return inst;
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            AffineTransform xform, Composite comp, Color bgcolor,
+            MultiRectArea clip) {
+
+        if(!srcSurf.isNativeDrawable()){
+            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                    sysxform, xform, comp, bgcolor, clip);
+        }else{
+            if(xform == null){
+                blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                        sysxform, comp, bgcolor, clip);
+            }else{
+                double scaleX = xform.getScaleX();
+                double scaleY = xform.getScaleY();
+                double scaledX = dstX / scaleX;
+                double scaledY = dstY / scaleY;
+                AffineTransform at = new AffineTransform();
+                at.setToTranslation(scaledX, scaledY);
+                xform.concatenate(at);
+                sysxform.concatenate(xform);
+                blit(srcX, srcY, srcSurf, 0, 0, dstSurf, width, height,
+                        sysxform, comp, bgcolor, clip);
+            }
+        }
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            Composite comp, Color bgcolor, MultiRectArea clip) {
+
+        if(!srcSurf.isNativeDrawable()){
+            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                    sysxform, comp, bgcolor, clip);
+        }else{
+            int type = sysxform.getType();
+            switch(type){
+                case AffineTransform.TYPE_TRANSLATION:
+                    dstX += sysxform.getTranslateX();
+                    dstY += sysxform.getTranslateY();
+                case AffineTransform.TYPE_IDENTITY:
+                    blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
+                            width, height, comp, bgcolor, clip);
+                    break;
+                default:
+                    // TODO Need to realize Affine Transformation
+                    if(srcSurf instanceof ImageSurface){
+                        JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, 
+                                dstSurf, width, height,
+                                sysxform, comp, bgcolor, clip);
+                    }else{
+                        int w = srcSurf.getWidth();
+                        int h = srcSurf.getHeight();
+                        BufferedImage tmp = new BufferedImage(w, h, 
+                                BufferedImage.TYPE_INT_RGB);
+                        Surface tmpSurf = Surface.getImageSurface(tmp);
+                        blit(0, 0, srcSurf, 0, 0, tmpSurf,
+                                w, h, AlphaComposite.SrcOver, null, null);
+                        JavaBlitter.inst.blit(srcX, srcY, tmpSurf, dstX, dstY, 
+                                dstSurf, width, height,
+                                sysxform, comp, bgcolor, clip);
+                    }
+            }
+        }
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+
+        if(!srcSurf.isNativeDrawable()){
+            JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf, width, height,
+                    comp, bgcolor, clip);
+        }else{
+            long dstSurfStruct = dstSurf.getSurfaceDataPtr();
+            Object dstData = dstSurf.getData();
+            int clipRects[];
+            if(clip != null){
+                clipRects = clip.rect;
+            }else{
+                clipRects = new int[]{5, 0, 0, dstSurf.getWidth(),
+                        dstSurf.getHeight()};
+            }
+
+            if(!(srcSurf instanceof ImageSurface)){
+                srcSurf = srcSurf.getImageSurface();
+                if(bgcolor != null){
+                    bgcolor = null;
+                }
+            }
+
+            long srcSurfStruct = srcSurf.getSurfaceDataPtr();
+            Object srcData = srcSurf.getData();
+            if(comp instanceof AlphaComposite){
+                AlphaComposite ac = (AlphaComposite) comp;
+                int compType = ac.getRule();
+                float alpha = ac.getAlpha();
+                if(bgcolor != null){
+                    bltBG(srcX, srcY, srcSurfStruct, srcData,
+                            dstX, dstY, dstSurfStruct, dstData,
+                            width, height, bgcolor.getRGB(),
+                            compType, alpha, clipRects, srcSurf.invalidated());
+                    dstSurf.invalidate();
+                    srcSurf.validate();
+                }else{
+                    blt(srcX, srcY, srcSurfStruct, srcData,
+                            dstX, dstY, dstSurfStruct, dstData,
+                            width, height, compType, alpha,
+                            clipRects, srcSurf.invalidated());
+                    dstSurf.invalidate();
+                    srcSurf.validate();
+                }
+            }else if(comp instanceof XORComposite){
+                XORComposite xcomp = (XORComposite) comp;
+                xor(srcX, srcY, srcSurfStruct, srcData,
+                        dstX, dstY, dstSurfStruct, dstData,
+                        width, height, xcomp.getXORColor().getRGB(),
+                        clipRects, srcSurf.invalidated());
+                dstSurf.invalidate();
+                srcSurf.validate();
+            }else{
+                if(srcSurf instanceof ImageSurface){
+                    JavaBlitter.inst.blit(srcX, srcY, srcSurf, dstX, dstY, 
+                            dstSurf, width, height,
+                            comp, bgcolor, clip);
+                }else{
+                    int w = srcSurf.getWidth();
+                    int h = srcSurf.getHeight();
+                    BufferedImage tmp = new BufferedImage(w, h, 
+                            BufferedImage.TYPE_INT_RGB);
+                    Surface tmpSurf = Surface.getImageSurface(tmp);
+                    long tmpSurfStruct = tmpSurf.getSurfaceDataPtr();
+                    Object tmpData = tmpSurf.getData();
+                    int tmpClip[] = new int[]{5, 0, 0, srcSurf.getWidth(),
+                            srcSurf.getHeight()};
+                    
+                    blt(0, 0, srcSurfStruct, srcData, 0, 0,
+                            tmpSurfStruct, tmpData, w, h, 
+                            AlphaComposite.SRC_OVER,
+                            1.0f, tmpClip, srcSurf.invalidated());
+                    srcSurf.validate();
+                    JavaBlitter.inst.blit(srcX, srcY, tmpSurf, dstX, dstY, 
+                            dstSurf, width, height,
+                            comp, bgcolor, clip);
+                }
+            }
+        }
+
+    }
+
+    private native void bltBG(int srcX, int srcY, long srsSurfDataPtr,
+            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
+            Object dstData, int width, int height, int bgcolor,
+            int compType, float alpha, int clip[], boolean invalidated);
+
+    private native void blt(int srcX, int srcY, long srsSurfDataPtr,
+            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
+            Object dstData, int width, int height, int compType,
+            float alpha, int clip[], boolean invalidated);
+
+    private native void xor(int srcX, int srcY, long srsSurfDataPtr,
+            Object srcData, int dstX, int dstY, long dstSurfDataPtr,
+            Object dstData, int width, int height, int xorcolor,
+            int clip[], boolean invalidated);
+
+
+}
diff --git a/awt/org/apache/harmony/awt/gl/render/NullBlitter.java b/awt/org/apache/harmony/awt/gl/render/NullBlitter.java
new file mode 100644
index 0000000..9032e4e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/gl/render/NullBlitter.java
@@ -0,0 +1,56 @@
+/*
+ *  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 Igor V. Stolyarov
+ * @version $Revision$
+ * Created on 07.12.2005
+ *
+ */
+package org.apache.harmony.awt.gl.render;
+
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.geom.AffineTransform;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.Surface;
+
+
+public class NullBlitter implements Blitter {
+
+    static Blitter inst = new NullBlitter();
+    public static Blitter getInstance(){
+        return inst;
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            AffineTransform xform, Composite comp, Color bgcolor,
+            MultiRectArea clip) {
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, AffineTransform sysxform,
+            Composite comp, Color bgcolor, MultiRectArea clip) {
+    }
+
+    public void blit(int srcX, int srcY, Surface srcSurf, int dstX, int dstY,
+            Surface dstSurf, int width, int height, Composite comp,
+            Color bgcolor, MultiRectArea clip) {
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/im/InputMethodContext.java b/awt/org/apache/harmony/awt/im/InputMethodContext.java
new file mode 100644
index 0000000..45ed11f
--- /dev/null
+++ b/awt/org/apache/harmony/awt/im/InputMethodContext.java
@@ -0,0 +1,563 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.im;
+
+//???AWT
+import java.awt.AWTEvent;
+import java.awt.Component;
+//import java.awt.KeyboardFocusManager;
+import java.awt.Rectangle;
+//import java.awt.Window;
+import java.awt.event.FocusEvent;
+import java.awt.event.InputMethodEvent;
+import java.awt.event.KeyEvent;
+import java.awt.font.TextHitInfo;
+import java.awt.im.InputContext;
+import java.awt.im.InputMethodRequests;
+import java.awt.im.spi.InputMethod;
+import java.awt.im.spi.InputMethodDescriptor;
+import java.lang.Character.Subset;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+//???AWT
+//import javax.swing.JFrame;
+
+import org.apache.harmony.awt.wtk.NativeIM;
+
+/**
+ * Implementation of InputMethodContext
+ * interface, also provides all useful
+ * functionality of InputContext
+ * 
+ */
+public class InputMethodContext extends InputContext implements
+        java.awt.im.spi.InputMethodContext {    
+
+    //???AWT
+    private InputMethod inputMethod; // current IM
+    private Component client; // current "active" client component
+    //???AWT: private CompositionWindow composeWindow; // composition Window    
+    private final Map<InputMethodDescriptor, InputMethod> imInstances; // Map<InputMethodDescriptor, InputMethod>
+    private final Map<Locale, InputMethod> localeIM; // Map<Locale, InputMethod> last user-selected IM for locale
+    private final Set<InputMethod> notifyIM; // set of IMs to notify of client window bounds changes
+    
+    /**
+     * a flag indicating that IM should be notified of client window
+     * position/visibility changes as soon as it is activated(new client
+     * appears)
+     */    
+    private boolean pendingClientNotify;
+    private Component nextComp; // component to gain focus after endComposition()
+    //???AWT: private final Set<Window> imWindows; // set of all IM windows created by this instance
+    private final NativeIM nativeIM;
+    
+
+ 
+    public InputMethodContext() {
+        notifyIM = new HashSet<InputMethod>();
+//???AWT:        imWindows = new HashSet<Window>();
+        imInstances = new HashMap<InputMethodDescriptor, InputMethod>();
+        localeIM = new HashMap<Locale, InputMethod>();
+        selectInputMethod(Locale.US); // not default?
+        nativeIM = (NativeIM) inputMethod;
+    }
+
+    //???AWT
+    /*
+    @Override
+    public void dispatchEvent(AWTEvent event) {
+        int id = event.getID(); 
+        if ((id >= FocusEvent.FOCUS_FIRST) && (id <=FocusEvent.FOCUS_LAST)) {
+            dispatchFocusEvent((FocusEvent) event);
+        } else {
+            // handle special KEY_PRESSED
+            // event to show IM selection menu
+            if (id == KeyEvent.KEY_PRESSED) {
+                KeyEvent ke = (KeyEvent) event;
+                IMManager.selectIM(ke, this, 
+                                   IMManager.getWindow(ke.getComponent()));
+            }
+            // dispatch all input events to the current IM:
+            if (inputMethod != null) {
+                inputMethod.dispatchEvent(event);
+            }
+        }
+    }
+    
+    private void dispatchFocusEvent(FocusEvent fe) {
+        switch (fe.getID()) {
+        case FocusEvent.FOCUS_LOST:            
+            if (inputMethod != null) {
+                inputMethod.deactivate(fe.isTemporary());                
+            }
+            break;
+        case FocusEvent.FOCUS_GAINED:
+            
+            Component comp = fe.getComponent();
+            if (imWindows.contains(comp)) {
+                // prevent activating when IM windows
+                // attached to this context gain focus                
+                return;
+            }
+            InputMethodContext lastActive = IMManager.getLastActiveIMC();
+            if ((lastActive != this) && (lastActive != null)) {
+                lastActive.hideWindows();
+            }
+            if (inputMethod != null) {
+                activateIM(inputMethod);
+                if (!getCompositionWindow().isEmpty()) {
+                    IMManager.showCompositionWindow(composeWindow);
+                }
+                if (client == comp) {
+                    if (nextComp != null) {
+                        // temporarily got focus to
+                        // end composition
+                        endComposition();
+
+                        // transfer focus to new client
+                        client = nextComp;
+                        nextComp = null;
+                        client.requestFocusInWindow();
+                    }
+                } else if ((client != null) && getCompositionWindow().isVisible()) {
+                    // temporarily return focus back
+                    // to previous client to be able
+                    // to end composition
+                    nextComp = comp;
+                    client.requestFocusInWindow();
+                } else {
+                    client = comp;
+                }
+            }
+            if (pendingClientNotify) {
+                notifyClientWindowChange(IMManager.getWindow(comp).getBounds());
+            }
+            break;
+        }
+
+    }
+
+    private void activateIM(InputMethod im) {
+        im.activate();
+        if ((nativeIM != null) && (im != nativeIM)) {
+            // when Java IM is active
+            // native input method editor must be
+            // explicitly disabled
+            nativeIM.disableIME();
+        }
+        IMManager.setLastActiveIMC(this);
+    }
+
+    @SuppressWarnings("deprecation")
+    private void hideWindows() {
+        if (inputMethod != null) {
+            inputMethod.hideWindows();
+        }
+        if (composeWindow != null) {
+            composeWindow.hide();
+        }
+    }
+
+    private void createCompositionWindow() {
+        composeWindow = new CompositionWindow(client);        
+    }
+    
+    private CompositionWindow getCompositionWindow() {
+        if (composeWindow == null) {
+            createCompositionWindow();
+        }
+        composeWindow.setClient(client);
+        return composeWindow;        
+    }
+    */
+    
+    /**
+     * Gets input method requests for the current client
+     * irrespective of input style.
+     * @return input method requests of composition window if
+     * client is passive,
+     * otherwise input method requests of client
+     */
+    private InputMethodRequests getIMRequests() {
+        InputMethodRequests imRequests = null;
+    
+        if (client != null) {
+            imRequests = client.getInputMethodRequests();
+            //???AWT
+            /*
+            if (imRequests == null) {                
+                imRequests = getCompositionWindow().getInputMethodRequests();
+            }
+            */
+        }
+        
+        return imRequests;
+    }
+    
+    /**
+     * Gets input method requests for the current client & input style.
+     * @return input method requests of composition window if
+     * input style is "below-the-spot"(or client is passive),
+     * otherwise client input method requests
+     */
+    private InputMethodRequests getStyleIMRequests() {
+        //???AWT
+        /*
+        if (IMManager.belowTheSpot()) {
+            return getCompositionWindow().getInputMethodRequests();
+        }
+        */
+        return getIMRequests();
+    }
+    
+    @Override
+    public void dispose() {
+        if (inputMethod != null) {
+            closeIM(inputMethod);
+            inputMethod.dispose();
+        }
+        notifyIM.clear();
+        super.dispose();
+    }
+
+    @Override
+    public void endComposition() {
+        if (inputMethod != null) {
+            inputMethod.endComposition();
+        }
+        super.endComposition();
+    }
+
+    @Override
+    public Object getInputMethodControlObject() {
+        if (inputMethod != null) {
+            return inputMethod.getControlObject();
+        }
+        return super.getInputMethodControlObject();
+    }
+
+    @Override
+    public Locale getLocale() {
+        if (inputMethod != null) {
+            return inputMethod.getLocale();
+        }
+        return super.getLocale();
+    }
+
+    @Override
+    public boolean isCompositionEnabled() {
+        if (inputMethod != null) {
+            return inputMethod.isCompositionEnabled();
+        }
+        return super.isCompositionEnabled();
+    }
+
+    @Override
+    public void reconvert() {
+        if (inputMethod != null) {
+            inputMethod.reconvert();
+        }
+        super.reconvert();
+    }
+
+    //???AWT
+    /*
+    @Override
+    public void removeNotify(Component client) {
+        if ((inputMethod != null) && (client == this.client)) {
+            inputMethod.removeNotify();
+            client = null;
+            // set flag indicating that IM should be notified
+            // as soon as it is activated(new client appears)
+            pendingClientNotify = true;
+        }
+        
+        super.removeNotify(client);
+    }
+    */
+
+    @Override
+    public boolean selectInputMethod(Locale locale) {        
+        
+        if ((inputMethod != null) && inputMethod.setLocale(locale)) {
+            return true;
+        }
+        // first
+        // take last user-selected IM for locale            
+        InputMethod newIM = localeIM.get(locale);
+        
+        // if not found search through IM descriptors
+        // and take already created instance if exists
+        // or create, store new IM instance in descriptor->instance map
+        //???AWT
+        /*
+        if (newIM == null) {
+            try {
+                newIM = getIMInstance(IMManager.getIMDescriptors().iterator(),
+                                      locale);
+            } catch (Exception e) {
+                // ignore exceptions - just return false
+            }
+        }
+        */
+        
+        return switchToIM(locale, newIM);
+    }
+
+    private boolean switchToIM(Locale locale, InputMethod newIM) {
+        //???AWT
+        /*
+        if (newIM != null) {
+            closeIM(inputMethod);
+            client = KeyboardFocusManager.
+            getCurrentKeyboardFocusManager().getFocusOwner();
+            initIM(newIM, locale);
+            inputMethod = newIM;
+            
+            return true;
+        }
+        */
+        return false;
+    }
+    
+    /**
+     * Is called when IM is selected from UI
+     */
+    void selectIM(InputMethodDescriptor imd, Locale locale) {
+        try {
+            switchToIM(locale, getIMInstance(imd));            
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Gets input method instance for the given
+     * locale from the given list of descriptors
+     * @param descriptors iterator of the list of IM descriptors
+     * @param locale the locale to be supported by the IM
+     * @return input method instance
+     * @throws Exception
+     */
+    private InputMethod getIMInstance(Iterator<InputMethodDescriptor> descriptors,
+                                      Locale locale) throws Exception {
+        while (descriptors.hasNext()) {
+            InputMethodDescriptor desc = descriptors.next();
+            Locale[] locs = desc.getAvailableLocales();
+            for (Locale element : locs) {
+                if (locale.equals(element)) {
+                    return getIMInstance(desc);
+                }
+            }
+        }
+        return null;
+    }
+
+    private InputMethod getIMInstance(InputMethodDescriptor imd) throws Exception {
+        InputMethod im = imInstances.get(imd);
+        if (im == null) {
+            im = imd.createInputMethod();
+            im.setInputMethodContext(this);
+            imInstances.put(imd, im);
+        }
+        return im;
+    }
+    
+    private void initIM(InputMethod im, Locale locale) {
+        if (im == null) {
+            return;
+        }
+        im.setLocale(locale);
+        im.setCharacterSubsets(null);
+        //???AWT: activateIM(im);
+        try {
+            im.setCompositionEnabled(inputMethod != null ? 
+                                     inputMethod.isCompositionEnabled() : true);
+        } catch (UnsupportedOperationException uoe) {
+
+        }
+        
+    }
+
+    private void closeIM(InputMethod im) {
+        if (im == null) {
+            return;
+        }
+        if (im.isCompositionEnabled()) {
+            im.endComposition();
+        }
+        
+        im.deactivate(true);
+        im.hideWindows();
+        
+    }
+    
+    @Override
+    public void setCharacterSubsets(Subset[] subsets) {
+        if (inputMethod != null) {
+            inputMethod.setCharacterSubsets(subsets);
+        }
+        super.setCharacterSubsets(subsets);
+    }
+
+    @Override
+    public void setCompositionEnabled(boolean enable) {
+        if (inputMethod != null) {
+            inputMethod.setCompositionEnabled(enable);
+        }
+        super.setCompositionEnabled(enable);
+    }
+
+    //???AWT
+    /*
+    public JFrame createInputMethodJFrame(String title,
+                                          boolean attachToInputContext) {
+        JFrame jf = new IMJFrame(title, attachToInputContext ? this : null);
+        imWindows.add(jf);
+        return jf;
+    }
+
+    public Window createInputMethodWindow(String title,
+                                          boolean attachToInputContext) {
+        Window w = new IMWindow(title, attachToInputContext ? this : null);
+        imWindows.add(w);
+        return w;
+    }
+    */
+    
+    @SuppressWarnings("deprecation")
+    public void dispatchInputMethodEvent(int id,
+                                         AttributedCharacterIterator text,
+                                         int committedCharacterCount,
+                                         TextHitInfo caret,
+                                         TextHitInfo visiblePosition) {
+        if (client == null) {
+            return;
+        }
+        //???AWT
+        /*
+        InputMethodEvent ime = new InputMethodEvent(client, id, text,
+                                                    committedCharacterCount,
+                                                    caret, visiblePosition);
+        
+
+        if ((client.getInputMethodRequests() != null) &&
+            !IMManager.belowTheSpot()) {
+            
+            client.dispatchEvent(ime);
+        } else {
+            
+            // show/hide composition window if necessary
+            if (committedCharacterCount < text.getEndIndex()) {
+                IMManager.showCompositionWindow(getCompositionWindow());
+            } else {
+                getCompositionWindow().hide();
+            }
+            composeWindow.getActiveClient().dispatchEvent(ime);
+        }
+        */
+        
+    }
+
+    public void enableClientWindowNotification(InputMethod inputMethod,
+                                               boolean enable) {
+        if (enable) {
+            notifyIM.add(inputMethod);
+            //???AWT
+            /*
+            if (client != null) {
+                notifyClientWindowChange(IMManager.getWindow(client).getBounds());
+            } else {
+                pendingClientNotify = true;
+            }
+            */
+        } else {
+            notifyIM.remove(inputMethod);
+        }
+        
+    }
+
+    public AttributedCharacterIterator cancelLatestCommittedText(
+                                                                 Attribute[] attributes) {
+        return getIMRequests().cancelLatestCommittedText(attributes);
+    }
+
+    public AttributedCharacterIterator getCommittedText(int beginIndex,
+                                                        int endIndex,
+                                                        Attribute[] attributes) {
+        return getIMRequests().getCommittedText(beginIndex, endIndex,
+                                                attributes);
+    }
+
+    public int getCommittedTextLength() {
+        return getIMRequests().getCommittedTextLength();
+    }
+
+    public int getInsertPositionOffset() {
+        return getIMRequests().getInsertPositionOffset();
+    }
+
+    public TextHitInfo getLocationOffset(int x, int y) {
+        InputMethodRequests imr = getStyleIMRequests();
+        if (imr != null) {
+            return imr.getLocationOffset(x, y);
+        }
+        return null;
+    }
+
+    public AttributedCharacterIterator getSelectedText(Attribute[] attributes) {
+        return getIMRequests().getSelectedText(attributes);
+    }
+
+    public Rectangle getTextLocation(TextHitInfo offset) {        
+        return getStyleIMRequests().getTextLocation(offset);
+    }
+    
+    /**
+     * To be called by AWT when client Window's bounds/visibility/state
+     * change
+     */
+    public void notifyClientWindowChange(Rectangle bounds) {
+        if (notifyIM.contains(inputMethod)) {
+            inputMethod.notifyClientWindowChange(bounds);
+        }
+        pendingClientNotify = false;
+    }
+
+    public final InputMethod getInputMethod() {
+        return inputMethod;
+    }
+
+    public final Component getClient() {
+        return client;
+    }
+
+    public final NativeIM getNativeIM() {
+        return nativeIM;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/internal/nls/Messages.java b/awt/org/apache/harmony/awt/internal/nls/Messages.java
new file mode 100644
index 0000000..96762c9
--- /dev/null
+++ b/awt/org/apache/harmony/awt/internal/nls/Messages.java
@@ -0,0 +1,143 @@
+/* 
+ * 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.
+ */
+
+/*
+ * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
+ * All changes made to this file manually will be overwritten 
+ * if this tool runs again. Better make changes in the template file.
+ */
+
+package org.apache.harmony.awt.internal.nls;
+
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+// BEGIN android-deleted
+/*
+ * For Android, this module is a separate library and not part of the
+ * boot classpath, so its resources won't be found on the boot classpath
+ * as is assumed by MsgHelp.getString(). We instead use a local MsgHelp
+ * which bottoms out in a call to the useful part of its lower-level
+ * namesake.
+ */
+//import org.apache.harmony.kernel.vm.VM;
+//import org.apache.harmony.luni.util.MsgHelp;
+// END android-deleted
+
+/**
+ * This class retrieves strings from a resource bundle and returns them,
+ * formatting them with MessageFormat when required.
+ * <p>
+ * It is used by the system classes to provide national language support, by
+ * looking up messages in the <code>
+ *    org.apache.harmony.awt.internal.nls.messages
+ * </code>
+ * resource bundle. Note that if this file is not available, or an invalid key
+ * is looked up, or resource bundle support is not available, the key itself
+ * will be returned as the associated message. This means that the <em>KEY</em>
+ * should a reasonable human-readable (english) string.
+ * 
+ */
+public class Messages {
+
+    // BEGIN android-deleted
+    //private static final String sResource =
+    //    "org.apache.harmony.awt.internal.nls.messages";
+    // END android-deleted
+
+    /**
+     * Retrieves a message which has no arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg) {
+        return MsgHelp.getString(msg);
+    }
+
+    /**
+     * Retrieves a message which takes 1 argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            Object the object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg) {
+        return getString(msg, new Object[] { arg });
+    }
+
+    /**
+     * Retrieves a message which takes 1 integer argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            int the integer to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, int arg) {
+        return getString(msg, new Object[] { Integer.toString(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 1 character argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            char the character to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, char arg) {
+        return getString(msg, new Object[] { String.valueOf(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 2 arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg1
+     *            Object an object to insert in the formatted output.
+     * @param arg2
+     *            Object another object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg1, Object arg2) {
+        return getString(msg, new Object[] { arg1, arg2 });
+    }
+
+    /**
+     * Retrieves a message which takes several arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param args
+     *            Object[] the objects to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object[] args) {
+        return MsgHelp.getString(msg, args);
+    }
+}
diff --git a/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java b/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java
new file mode 100644
index 0000000..b57fe11
--- /dev/null
+++ b/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java
@@ -0,0 +1,86 @@
+/*
+ *  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.
+ */
+
+/*
+ * This implementation is based on the class of the same name in
+ * org.apache.harmony.luni.util.
+ */
+
+package org.apache.harmony.awt.internal.nls;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.logging.Logger;
+import java.util.Locale;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.util.MissingResourceException;
+
+/**
+ * This class contains helper methods for loading resource bundles and
+ * formatting external message strings.
+ */
+public final class MsgHelp {
+    /** name of the resource for this class */
+    private static final String RESOURCE_NAME =
+        "/org/apache/harmony/awt/internal/nls/messages.properties";
+
+    /** the resource bundle for this class */
+    private static final ResourceBundle THE_BUNDLE;
+
+    static {
+        ResourceBundle rb = null;
+
+        try {
+            InputStream in = MsgHelp.class.getResourceAsStream(
+                    RESOURCE_NAME);
+            rb = new PropertyResourceBundle(in);
+        } catch (IOException ex) {
+            Logger.global.warning("Couldn't read resource bundle: " +
+                    ex);
+        } catch (RuntimeException ex) {
+            // Shouldn't happen, but deal at least somewhat gracefully.
+            Logger.global.warning("Couldn't find resource bundle: " +
+                    ex);
+        }
+
+        THE_BUNDLE = rb;
+    }
+    
+    public static String getString(String msg) {
+        if (THE_BUNDLE == null) {
+            return msg;
+        }
+        try {
+            return THE_BUNDLE.getString(msg);
+        } catch (MissingResourceException e) {
+            return "Missing message: " + msg;
+        }
+    }
+    
+    static public String getString(String msg, Object[] args) {
+        String format = msg;
+        if (THE_BUNDLE != null) {
+            try {
+                format = THE_BUNDLE.getString(msg);
+            } catch (MissingResourceException e) {
+            }
+        }
+
+        return org.apache.harmony.luni.util.MsgHelp.format(format, args);
+    }
+}
diff --git a/awt/org/apache/harmony/awt/state/MenuItemState.java b/awt/org/apache/harmony/awt/state/MenuItemState.java
new file mode 100644
index 0000000..b13e50b
--- /dev/null
+++ b/awt/org/apache/harmony/awt/state/MenuItemState.java
@@ -0,0 +1,51 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.state;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+
+/**
+ * State of menu item
+ */
+
+public interface MenuItemState {
+
+    String getText();
+    Rectangle getTextBounds();
+    void setTextBounds(int x, int y, int w, int h);
+
+    String getShortcut();
+    Rectangle getShortcutBounds();
+    void setShortcutBounds(int x, int y, int w, int h);
+
+    Rectangle getItemBounds();
+    void setItemBounds(int x, int y, int w, int h);
+
+    boolean isMenu();
+    boolean isChecked();
+    boolean isEnabled();
+
+    boolean isCheckBox();
+    boolean isSeparator();
+
+    Dimension getMenuSize();
+}
diff --git a/awt/org/apache/harmony/awt/state/MenuState.java b/awt/org/apache/harmony/awt/state/MenuState.java
new file mode 100644
index 0000000..564a49a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/state/MenuState.java
@@ -0,0 +1,46 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.state;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Point;
+
+/**
+ * State of pop-up or drop-down menu
+ */
+
+public interface MenuState {
+    int getWidth();
+    int getHeight();
+    Point getLocation();
+
+    void setSize(int w, int h);
+
+    Font getFont();
+    boolean isFontSet();
+    FontMetrics getFontMetrics(Font f);
+
+    int getItemCount();
+    int getSelectedItemIndex();
+
+    MenuItemState getItem(int index);
+}
diff --git a/awt/org/apache/harmony/awt/state/State.java b/awt/org/apache/harmony/awt/state/State.java
new file mode 100644
index 0000000..4b8706d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/state/State.java
@@ -0,0 +1,55 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.state;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Rectangle;
+
+/**
+ * State of the component
+ */
+public interface State {
+
+    boolean isEnabled();
+    boolean isVisible();
+    boolean isFocused();
+
+    Font getFont();
+    boolean isFontSet();
+    FontMetrics getFontMetrics();
+
+    Color getBackground();
+    boolean isBackgroundSet();
+
+    Color getTextColor();
+    boolean isTextColorSet();
+
+    Rectangle getBounds();
+    Dimension getSize();
+
+    Dimension getDefaultMinimumSize();
+    void setDefaultMinimumSize(Dimension size);
+
+    long getWindowId();
+}
diff --git a/awt/org/apache/harmony/awt/wtk/CreationParams.java b/awt/org/apache/harmony/awt/wtk/CreationParams.java
new file mode 100644
index 0000000..63c581d
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/CreationParams.java
@@ -0,0 +1,133 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+/**
+ * This class describes cross-platform NativeWindow creation params
+ * See also WindowFactory.createWindow
+ */
+public class CreationParams {
+    /**
+     * Initial state is maximized verticaly
+     */
+    public final long MAXIMIZED_VERT = 1;
+    /**
+     * Initial state is maximized horizontaly
+     */
+    public final long MAXIMIZED_HORIZ = 2;
+    /**
+     * Initial state is maximized both
+     * horizontaly and verticaly
+     */
+    public final long MAXIMIZED = 3;
+
+    /**
+     * The top-level window that has all possible decorations,
+     * has no owner and is displayed in taskbar
+     */
+    public final static int DECOR_TYPE_FRAME = 1;
+    /**
+     * The dialog window
+     */
+    public final static int DECOR_TYPE_DIALOG = 2;
+    /**
+     * The transient undecorated pop-up window
+     */
+    public final static int DECOR_TYPE_POPUP = 3;
+    /**
+     * The undecoraded pop-up window
+     */
+    public final static int DECOR_TYPE_UNDECOR = 4;
+    /**
+     * Non-MDI child window
+     */
+    public final static int DECOR_TYPE_NONE = 0;
+
+    /**
+     * Initial x.
+     */
+    public int x = 0;
+    /**
+     * Initial y.
+     */
+    public int y = 0;
+    /**
+     * Initial width.
+     */
+    public int w = 1;
+    /**
+     * Initial height.
+     */
+    public int h = 1;
+    /**
+     * The decoration type of the top-level window. The possible values are:
+     * DECOR_TYPE_FRAME, DECOR_TYPE_DIALOG, DECOR_TYPE_POPUP and DECOR_TYPE_UNDECOR
+     */
+    public int decorType = DECOR_TYPE_NONE;
+    /**
+     * Window is child of parent, otherwise it's
+     * toplevel(child of desktop) window owned by parent.
+     */
+    public boolean child = false;
+    /**
+     * Window is resizable
+     */
+    public boolean resizable = true;
+    /**
+     * The window has no decorations
+     */
+    public boolean undecorated = false;
+    /**
+     * Initial visibility state.
+     */
+    public boolean visible = false;
+    /**
+     * Window is ALWAYS topmost in Z order.
+     */
+    public boolean topmost = false;
+    /**
+     * Window is disabled.
+     */
+    public boolean disabled = false;
+    /**
+     * Window initially iconified.
+     */
+    public boolean iconified = false;
+    /**
+     * Bitwise OR of MAXIMIZED_* constants.
+     * Means if window is initially maximized.
+     */
+    public int maximizedState = 0;
+    /**
+     * Tells that window position should be determined by native windowing system 
+     */
+    public boolean locationByPlatform = false;
+    /**
+     * Id of parent or owner window, see child field
+     * For non-child window without owner equals 0.
+     */
+    public long parentId = 0;
+    /**
+     * Name wich is displayed on titlebar, taskbar and visible
+     * for system requests.
+     */
+    public String name = null;
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/awt/wtk/CursorFactory.java b/awt/org/apache/harmony/awt/wtk/CursorFactory.java
new file mode 100644
index 0000000..35e7d33
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/CursorFactory.java
@@ -0,0 +1,85 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Dimension;
+import java.awt.Image;
+
+/**
+ * Provides factory for NativeCursor
+ */
+public abstract class CursorFactory {
+    protected NativeCursor[] systemCursors = {
+            null, null, null, null,
+            null, null, null, null,
+            null, null, null, null,
+            null, null,
+    };
+    /**
+     * Creates and returns NativeCursor for predefined
+     * Java Cursor
+     *
+     * @param type - type of predefined Java Cursor
+     * @return created cursor
+     */
+    public abstract NativeCursor createCursor(int type);
+
+    /**
+     * Gets a cached instance of system(predefined) native cursor
+     * or creates a new one. This is a platform-independent method.
+     *
+     * @param type - type of predefined Java Cursor
+     * @return created cursor
+     */
+    public NativeCursor getCursor(int type) {
+        if (type >= 0 && type < systemCursors.length) {
+            NativeCursor cursor = systemCursors[type];
+            if (cursor == null) {
+                cursor = createCursor(type);
+                systemCursors[type] = cursor;
+            }
+            return cursor;
+        }
+        return null;
+    }
+    /**
+     * Creates and returns custom NativeCursor from image
+     *
+     * @param img - image(source) to create cursor from
+     * @param xHotSpot - x coordinate of the hotspot relative to the source's origin
+     * @param yHotSpot - y coordinate of the hotspot relative to the source's origin
+     * @return created cursor
+     */
+    public abstract NativeCursor createCustomCursor(Image img, int xHotSpot, int yHotSpot);
+
+    /**
+     * Query native system for the best cursor size closest to specified dimensions
+     * @param prefWidth - preferred width
+     * @param prefHeight - preferred height
+     * @return closest supported dimensions to ones specified
+     */
+    public abstract Dimension getBestCursorSize(int prefWidth, int prefHeight);
+
+    /**
+     * @return maximum number of colors supported by custom cursors
+     */
+    public abstract int getMaximumCursorColors();
+}
diff --git a/awt/org/apache/harmony/awt/wtk/GraphicsFactory.java b/awt/org/apache/harmony/awt/wtk/GraphicsFactory.java
new file mode 100644
index 0000000..0d7c84f
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/GraphicsFactory.java
@@ -0,0 +1,82 @@
+/*
+ *  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 Pavel Dolgov, Alexey A. Petrenko, Oleg V. Khaschansky
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.peer.FontPeer;
+import org.apache.harmony.awt.gl.MultiRectArea;
+import org.apache.harmony.awt.gl.font.FontManager;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+
+
+/**
+ * GraphicsFactory interface defines methods for Graphics2D 
+ * and font stuff instances factories.
+ */
+public interface GraphicsFactory {
+    static final FontMetrics cacheFM[] =  new FontMetrics[10];
+    
+    /**
+     * This method creates Graphics2D instance for specified native window.
+     *  
+     * @param win Native window to draw
+     * @param translateX Translation along X axis
+     * @param translateY Translation along Y axis
+     * @param clip Clipping area for a new Graphics2D instance
+     * @return New Graphics2D instance for specified native window
+     * @deprecated
+     */
+    @Deprecated
+    Graphics2D getGraphics2D(NativeWindow win, int translateX, int translateY, MultiRectArea clip);
+
+    /**
+     * This method creates Graphics2D instance for specified native window.
+     *  
+     * @param win Native window to draw
+     * @param translateX Translation along X axis
+     * @param translateY Translation along Y axis
+     * @param width Width of drawing area
+     * @param height Height of drawing area
+     * @return New Graphics2D instance for specified native window
+     */
+    Graphics2D getGraphics2D(NativeWindow win, int translateX, int translateY, int width, int height);
+    // ???AWT: not standard harmony
+    Graphics2D getGraphics2D(Canvas c, Paint p);
+    
+    /**
+     * Creates instance of GraphicsEnvironment for specified WindowFactory
+     *  
+     * @param wf WindowFactory
+     * @return New instance of GraphicsEnvironment
+     */
+    GraphicsEnvironment createGraphicsEnvironment(WindowFactory wf);
+    
+    // Font methods
+    FontMetrics getFontMetrics(Font font);
+    FontManager getFontManager();
+    FontPeer getFontPeer(Font font);
+    Font embedFont(String fontFilePath);
+}
diff --git a/awt/org/apache/harmony/awt/wtk/KeyInfo.java b/awt/org/apache/harmony/awt/wtk/KeyInfo.java
new file mode 100644
index 0000000..1f8a29a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/KeyInfo.java
@@ -0,0 +1,53 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.event.KeyEvent;
+
+/**
+ * Keystroke information
+ */
+
+public final class KeyInfo {
+
+    public int vKey;
+    public int keyLocation;
+    public final StringBuffer keyChars;
+
+    public static final int DEFAULT_VKEY = KeyEvent.VK_UNDEFINED;
+    public static final int DEFAULT_LOCATION = KeyEvent.KEY_LOCATION_STANDARD;
+
+    public KeyInfo() {
+        vKey = DEFAULT_VKEY;
+        keyLocation = DEFAULT_LOCATION;
+        keyChars = new StringBuffer();
+    }
+
+    public void setKeyChars(char ch) {
+        keyChars.setLength(0);
+        keyChars.append(ch);
+    }
+
+    public void setKeyChars(StringBuffer sb) {
+        keyChars.setLength(0);
+        keyChars.append(sb);
+    }
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeCursor.java b/awt/org/apache/harmony/awt/wtk/NativeCursor.java
new file mode 100644
index 0000000..2c6eb1e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeCursor.java
@@ -0,0 +1,45 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+/**
+ * The interface provides access to platform dependent functionality
+ * for the class java.awt.Cursor.
+ */
+public interface NativeCursor {
+    /**
+     * Sets the current cursor shape
+     * to this cursor when a pointer is inside
+     * @param winID - window(currently used only on X11)
+     */
+    void setCursor(long winID);
+    /**
+     * Destroys the native resource associated with
+     * this cursor
+     */
+    void destroyCursor();
+
+    /**
+     * @return Native handle associated with this cursor
+     */
+    long getId();
+
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeEvent.java b/awt/org/apache/harmony/awt/wtk/NativeEvent.java
new file mode 100644
index 0000000..1471c1a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeEvent.java
@@ -0,0 +1,268 @@
+/*
+ *  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 Mikhail Danilov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+
+
+/**
+ * The interface describing cross-platform translation of system
+ * messages.
+ *
+ * <p/>Some messages can appear only on specific platform,
+ * but they still can have cross-platform interpretation if the
+ * application should be aware of them and can react using
+ * cross-platform API.
+ *
+ */
+public abstract class NativeEvent {
+
+    /**
+     * Message has no common cross-platform
+     * interpretation and should be skipped.
+     */
+    public static final int ID_PLATFORM = 0;
+
+    /**
+     * Window bounds have changed.
+     */
+    public static final int ID_BOUNDS_CHANGED = -1;
+
+    /**
+     * Window decoration size has changed.
+     */
+    public static final int ID_INSETS_CHANGED = -2;
+
+    /**
+     * Window was just created (WM_CREATE on Windows)
+     */
+    public static final int ID_CREATED = -3;
+
+    /**
+     * Mouse grab was canceled by the native system
+     */
+    public static final int ID_MOUSE_GRAB_CANCELED = -4;
+
+    /**
+     * System color scheme or visual theme was changed
+     */
+    public static final int ID_THEME_CHANGED = -5;
+
+    protected long windowId;
+    protected int eventId;
+    protected long otherWindowId;
+
+    protected Point screenPos;
+    protected Point localPos;
+    protected Rectangle windowRect;
+
+    protected int modifiers;
+    protected int mouseButton;
+    protected int wheelRotation;
+
+    protected KeyInfo keyInfo = new KeyInfo();
+
+    protected int windowState = -1;
+    protected long time;
+
+    /**
+     * Returns the system window id of the event recipient.
+     * @return HWND on Windows, xwindnow on X
+     */
+    public long getWindowId() {
+        return windowId;
+    }
+
+    /**
+     * Returns cross-platform event id
+     * should be one of ID_* constants or
+     * id constants from java.awt.AWTEvent subclasess
+     * @return cross-platform event id
+     */
+    public int getEventId() {
+        return eventId;
+    }
+
+    /**
+     * Returns the position of cursor when event occured relative to
+     * top-left corner of recipient window
+     * @return position of cursor in local coordinates
+     */
+    public Point getLocalPos() {
+        return localPos;
+    }
+
+    /**
+     * Returns the position of cursor when event occured
+     * in screen coordinates.
+     * @return position of cursor in screen coordinates
+     */
+    public Point getScreenPos() {
+        return screenPos;
+    }
+
+    /**
+     * The recipient window bounds when the event occured
+     * @return window bounds
+     */
+    public Rectangle getWindowRect() {
+        return windowRect;
+    }
+
+    /**
+     * Returns the state of keyboard and mouse buttons when the event
+     * occured if event from mouse or keyboard, for other events can
+     * return junk values. The value is bitwise OR of
+     * java.awt.event.InputEvent *_DOWN constants.
+     *
+     * Method is aware of system mouse button swap for left-hand
+     * mouse and return swapped values.
+     * @return bitwise OR of java.awt.event.InputEvent *_DOWN constants
+     */
+    public int getInputModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * Returns the iconified/maximized state of recipient window if
+     * event is state related, for other events can junk values.
+     * The value has the same meaning as Frame.getExtendedState
+     * It's bitwise OR of ICONIFIED, MAXIMIZED_HORIZ, MAXIMIZED_VERT
+     * @return bitwise OR of ICONIFIED, MAXIMIZED_HORIZ, MAXIMIZED_VERT
+     */
+    public int getWindowState() {
+        return windowState;
+    }
+
+    /**
+     * The same meaning as java.awt.event.getKeyCode
+     * @return java.awt.event VK_* constant
+     */
+    public int getVKey() {
+        return (keyInfo != null) ? keyInfo.vKey : KeyInfo.DEFAULT_VKEY;
+    }
+
+    /**
+     * The same meaning as java.awt.event.getKeyLocation
+     * @return java.awt.event KEY_LOCATION_* constant
+     */
+    public int getKeyLocation() {
+        return (keyInfo != null) ? keyInfo.keyLocation : KeyInfo.DEFAULT_LOCATION;
+    }
+
+    /**
+     * Return the string of characters associated with the event
+     * Has meaning only for KEY_PRESSED as should be translated to
+     * serie of KEY_TYPED events. For dead keys and input methods
+     * one key press can generate multiple key chars.
+     * @return string of characters
+     */
+    public StringBuffer getKeyChars() {
+        if (keyInfo == null) {
+            return null;
+        }
+        if (keyInfo.vKey == KeyEvent.VK_ENTER) {
+            keyInfo.keyChars.setLength(0);
+            keyInfo.setKeyChars('\n');
+        }
+        return keyInfo.keyChars;
+    }
+
+    public char getLastChar() {
+        if (keyInfo == null || keyInfo.keyChars.length() == 0) {
+            return KeyEvent.CHAR_UNDEFINED;
+        }
+        return keyInfo.keyChars.charAt(keyInfo.keyChars.length()-1);
+    }
+
+    /**
+     * Returns the number of mouse button which changed it's state,
+     * otherwise 0.
+     * Left button is 1, middle button is 2, right button is 3.
+     *
+     * Method is aware of system mouse button swap for left-hand
+     * mouse and return swapped values.
+     * @return mouse button number
+     */
+    public int getMouseButton() {
+        return mouseButton;
+    }
+
+    /**
+     * Returns time when the message was received
+     * @return time in milliseconds
+     */
+    public long getTime() {
+        return time;
+    }
+
+    /**
+     * For the focus event contains the oposite window.
+     * This means it lost focus if recipient gains it,
+     * or will gain focus if recipient looses it.
+     * @return HWND on Windows, xwindnow on X
+     */
+    public long getOtherWindowId() {
+        return otherWindowId;
+    }
+
+    /**
+     * Returns the "dirty" area of the window as set of non-intersecting
+     * rectangles. This area is to be painted.
+     * @return non-empty array of null if empty
+     */
+    public abstract MultiRectArea getClipRects();
+
+    /**
+     * Returns the "dirty" area of the window as one rectangle.
+     * This area is to be painted.
+     * @return non-null Rectangle
+     */
+    public abstract Rectangle getClipBounds();
+
+    /**
+     * Returns the window insets. Insets is area which belongs to
+     * window somehow but is outside of it's client area,
+     * it usually contains system provided border and titlebar.
+     * @return non-null java.awt.Insets
+     */
+    public abstract Insets getInsets();
+
+    /**
+     * Returns true if event is popup menu trigger.
+     * @return boolean flag
+     */
+    public abstract boolean getTrigger();
+
+    /**
+     * Returns the number of "clicks" the mouse wheel was rotated.
+     * @return negative values if the mouse wheel was rotated up/away from the user,
+     * and positive values if the mouse wheel was rotated down/ towards the user
+     */
+    public int getWheelRotation() {
+        return wheelRotation;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeEventQueue.java b/awt/org/apache/harmony/awt/wtk/NativeEventQueue.java
new file mode 100644
index 0000000..0738cd1
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeEventQueue.java
@@ -0,0 +1,117 @@
+/*
+ *  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 Mikhail Danilov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.util.LinkedList;
+
+
+/**
+ * Describes the cross-platform native event queue interface
+ *
+ * <p/> The implementation constructor should remember thread it was
+ * created. All other methods would be called obly from this thread,
+ * except awake().
+ */
+public abstract class NativeEventQueue {
+    
+    private ShutdownWatchdog shutdownWatchdog;
+    private class EventMonitor {}
+    private final Object eventMonitor = new EventMonitor();
+    private final LinkedList<NativeEvent> eventQueue = new LinkedList<NativeEvent>();
+
+    public static abstract class Task {
+        public volatile Object returnValue;
+
+        public abstract void perform();
+    }
+    
+    /**
+     * Blocks current thread until native event queue is not empty
+     * or awaken from other thread by awake().
+     *
+     * <p/>Should be called only on tread which
+     * will process native events.
+     *
+     * @return if event loop should be stopped
+     */
+    public abstract boolean waitEvent();
+
+    /**
+     * Determines whether or not the native event queue is empty.
+     * An queue is empty if it contains no messages waiting.
+     *
+     * @return true if the queue is empty; false otherwise
+     */
+    public boolean isEmpty() {
+        synchronized(eventQueue) {
+            return eventQueue.isEmpty();
+        }
+    }
+
+    public NativeEvent getNextEvent() {
+        synchronized (eventQueue) {
+            if (eventQueue.isEmpty()) {
+                shutdownWatchdog.setNativeQueueEmpty(true);
+                return null;
+            }
+            return eventQueue.remove(0);
+        }
+    }
+    
+    protected void addEvent(NativeEvent event) {
+        synchronized (eventQueue) {
+            eventQueue.add(event);
+            shutdownWatchdog.setNativeQueueEmpty(false);
+        }
+        synchronized (eventMonitor) {
+            eventMonitor.notify();
+        }
+    }
+
+    public final Object getEventMonitor() {
+        return eventMonitor;
+    }
+
+    public abstract void awake();
+
+    /**
+     * Gets AWT system window ID.
+     *
+     * @return AWT system window ID
+     */
+    public abstract long getJavaWindow();
+
+    /**
+     * Add NativeEvent to the queue
+     */
+    public abstract void dispatchEvent();
+
+    public abstract void performTask(Task task);
+
+    public abstract void performLater(Task task);
+    
+    public final void setShutdownWatchdog(ShutdownWatchdog watchdog) {
+        synchronized (eventQueue) {
+            shutdownWatchdog = watchdog;
+        }
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeEventThread.java b/awt/org/apache/harmony/awt/wtk/NativeEventThread.java
new file mode 100644
index 0000000..d50add4
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeEventThread.java
@@ -0,0 +1,78 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+
+/**
+ * NativeEventThread
+ */
+public class NativeEventThread extends Thread {
+    
+    public interface Init {
+        WTK init();
+    }
+    
+    NativeEventQueue nativeQueue;
+    Init init;
+    
+    private WTK wtk;
+    
+    public NativeEventThread() {
+        super("AWT-NativeEventThread"); //$NON-NLS-1$
+        setDaemon(true);
+    }
+
+    @Override
+    public void run() {
+        synchronized (this) {
+            try {
+                wtk = init.init();
+                nativeQueue = wtk.getNativeEventQueue();
+            } finally {
+                notifyAll();
+            }
+        }
+        
+        runModalLoop();
+    }
+
+    void runModalLoop() {
+        while (nativeQueue.waitEvent()) {
+            nativeQueue.dispatchEvent();
+        }
+    }
+    
+    public void start(Init init) {
+        synchronized (this) {
+            this.init = init;
+            super.start();
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+    
+    public WTK getWTK() {
+        return wtk;
+    }
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeIM.java b/awt/org/apache/harmony/awt/wtk/NativeIM.java
new file mode 100644
index 0000000..1626f4a
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeIM.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.
+ */
+/** 
+ * @author Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.AWTEvent;
+import java.awt.AWTException;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.im.spi.InputMethod;
+import java.awt.im.spi.InputMethodContext;
+import java.awt.im.spi.InputMethodDescriptor;
+import java.lang.Character.Subset;
+import java.util.Locale;
+
+/**
+ * A cross-platform interface for native input
+ * method sub-system functionality.
+ */
+public abstract class NativeIM implements InputMethod, InputMethodDescriptor {
+    protected InputMethodContext imc;
+
+    public void activate() {
+
+    }
+
+    public void deactivate(boolean isTemporary) {
+
+    }
+
+    public void dispatchEvent(AWTEvent event) {
+
+    }
+
+    public void dispose() {
+
+    }
+
+    public void endComposition() {
+
+    }
+
+    public Object getControlObject() {
+        return null;
+    }
+
+    public Locale getLocale() {
+        return null;
+    }
+
+    public void hideWindows() {
+
+    }
+
+    public boolean isCompositionEnabled() {
+        return false;
+    }
+
+    public void notifyClientWindowChange(Rectangle bounds) {
+
+    }
+
+    public void reconvert() {
+
+    }
+
+    public void removeNotify() {
+
+    }
+
+    public void setCharacterSubsets(Subset[] subsets) {
+
+    }
+    
+    public void setCompositionEnabled(boolean enable) {
+
+    }
+
+    public void setInputMethodContext(InputMethodContext context) {
+        imc = context;
+    }
+
+    public boolean setLocale(Locale locale) {
+        return false;
+    }
+
+    public Locale[] getAvailableLocales() throws AWTException {
+    	return new Locale[]{Locale.getDefault(), Locale.ENGLISH};
+        //return new Locale[]{Locale.getDefault(), Locale.US};
+    }
+
+    public InputMethod createInputMethod() throws Exception {        
+        return this;
+    }
+
+    public String getInputMethodDisplayName(Locale inputLocale,
+                                            Locale displayLanguage) {
+        return "System input methods"; //$NON-NLS-1$
+    }
+
+    public Image getInputMethodIcon(Locale inputLocale) {
+        return null;
+    }
+
+    public boolean hasDynamicLocaleList() {
+        return false;
+    }
+    
+    public abstract void disableIME();
+    
+//    public abstract void disableIME(long id);
+
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeMouseInfo.java b/awt/org/apache/harmony/awt/wtk/NativeMouseInfo.java
new file mode 100644
index 0000000..0696975
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeMouseInfo.java
@@ -0,0 +1,42 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Point;
+
+/**
+ * The interface provides access to platform dependent functionality
+ * for classes java.awt.PointerInfo & java.awt.MouseInfo.
+ */
+public interface NativeMouseInfo {
+
+    /**
+     * Returns the Point that represents
+     * the coordinates of the pointer on the screen.
+     */
+    Point getLocation();
+
+    /**
+     * Returns the number of buttons on the mouse.
+     * If no mouse is installed returns -1.
+     */
+    int getNumberOfButtons();
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeRobot.java b/awt/org/apache/harmony/awt/wtk/NativeRobot.java
new file mode 100644
index 0000000..0b354d0
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeRobot.java
@@ -0,0 +1,75 @@
+/*
+ *  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 Dmitry A. Durnev
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+
+/**
+ * A cross-platform interface for java.awt.Robot implementation
+ */
+public interface NativeRobot {
+
+    /**
+     * @see java.awt.Robot#createScreenCapture(Rectangle)
+     * @param screenRect rectangle to capture in screen coordinates
+     * @return the captured image or null if
+     * capture failed.
+     */
+    BufferedImage createScreenCapture(Rectangle screenRect);
+
+    /**
+     * @see java.awt.Robot#getPixelColor(int, int)
+     */
+    Color getPixel(int x, int y);
+
+    /**
+     * Generate a native system keyboard input event.
+     * @param keycode A Java virtual key code
+     * @param press A key is pressed if true, released otherwise
+     * @see java.awt.Robot#keyPress(int)
+     * @throws IllegalArgumentException if keycode is invalid in the native system
+     */
+    void keyEvent(int keycode, boolean press);
+
+    /**
+     * Generate a native system mouse button(s) press or release event.
+     * @param buttons A mask of Java mouse button flags
+     * @param press buttons are pressed if true, released otherwise
+     * @see java.awt.Robot#mousePress(int)
+     */
+    void mouseButton(int buttons, boolean press);
+
+    /**
+     * Generate a native system mouse motion event.
+     *
+     * @see java.awt.Robot#mouseMove(int, int)
+     */
+    void mouseMove(int x, int y);
+
+    /**
+     * Generate a native system mouse wheel event.
+     *
+     * @see java.awt.Robot#mouseWheel(int)
+     */
+    void mouseWheel(int wheelAmt);
+}
diff --git a/awt/org/apache/harmony/awt/wtk/NativeWindow.java b/awt/org/apache/harmony/awt/wtk/NativeWindow.java
new file mode 100644
index 0000000..73fd6c0
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/NativeWindow.java
@@ -0,0 +1,220 @@
+/*
+ *  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 Mikhail Danilov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import org.apache.harmony.awt.gl.MultiRectArea;
+
+
+/**
+ * Provides cross-platform way to manipulate native window.
+ *
+ * Results of methods are reported through native messages.
+ */
+public interface NativeWindow {
+    /**
+     * Returns system id of the associated window
+     * @return HWND on Windows, xwindow on X
+     */
+    long getId();
+
+    /**
+     * Shows/hides window
+     * @param v - new visibility
+     */
+    void setVisible(boolean v);
+
+    /**
+     * Means only size should be changed
+     */
+    static final int BOUNDS_NOMOVE = 1;
+
+    /**
+     * Means only position should be changed
+     */
+    static final int BOUNDS_NOSIZE = 2;
+
+    /**
+     * Tries to set desired window bounds. It's not gurantied the
+     * property will have the desired value. The value change
+     * should be reported by system event (as for other properties).
+     *
+     * <p/>  If child, position is relative to parent window.
+     * @param x - desired x
+     * @param y - desired y
+     * @param w - desired width
+     * @param h - desired height
+     * @param boundsMask - bitwise OR of BOUNDS_* constants.
+     * Governs the new bounds interpretation.
+     */
+    void setBounds(int x, int y, int w, int h, int boundsMask);
+
+    /**
+     * Returns last notified window bounds. This means the last bounds
+     * reported by system event.
+     *
+     * <p/>  If child, position is relative to parent window.
+     * @return last notified window bounds
+     */
+    Rectangle getBounds();
+
+    /**
+     * Returns last notified insets. This means the last insets
+     * reported by system event. Insets are margins around client area
+     * ocupied by system provided decor, ususally border and titlebar.
+     * @return last notified insets
+     */
+    Insets getInsets();
+
+    /**
+     * Enables/disables processing of input (key, mouse) event
+     * by window. If disabled input events are ignored.
+     * @param value - if enabled
+     */
+    void setEnabled(boolean value);
+
+    /**
+     * Sets the "focusable" window state.
+     * @param value - if true makes window focusable
+     */
+    void setFocusable(boolean value);
+
+    /**
+     *
+     * @return current focusable window state
+     */
+    boolean isFocusable();
+
+    /**
+     * Tries to set application input focus to the window or clear
+     * current focus from focused window.
+     *
+     * <p/> For toplevel windows it's not gurantied focus will land in
+     * desired window even if function returns true. Focus traversal should be tracked
+     * by processing system events.
+     *
+     * @param focus  - if true sets focus, else clears focus
+     * @return if success
+     */
+    boolean setFocus(boolean focus);
+
+    /**
+     * Destroys the asscoiated window.
+     * Attempts to use it thereafter can result in
+     * unpredictable bechavior.
+     */
+    void dispose();
+
+    /**
+     * Changes window Z-order to place this window under, If w is null
+     * places places this window on the top. Z-order is per parent.
+     * Toplevels a children of desktop in terms of Z-order.
+     * @param w - window to place under.
+     */
+    void placeAfter(NativeWindow w);
+
+    /**
+     * Places window on top of Z-order
+     */
+    void toFront();
+
+    /**
+     * Places window on bottom of Z-order
+     */
+    void toBack();
+
+    /**
+     * Makes the window resizable/not resizable by user
+     * @param value - if resizable
+     */
+    void setResizable(boolean value);
+
+    /**
+     * Sets the window caption
+     * @param title - caption text
+     */
+    void setTitle(String title);
+
+    /**
+     * Activate the mouse event capturing
+     */
+    void grabMouse();
+
+    /**
+     * Deactivate mouse event capturing
+     */
+    void ungrabMouse();
+
+    /**
+     * Set extended state for top-level window.
+     *
+     * @param state - new state, bitmask of ICONIFIED, MAXIMIZED_BOTH, etc.
+     */
+    void setState(int state);
+
+    /**
+     * Set the image to be displayed in the minimized icon for
+     * top-level [decorated] window.
+     * @param image the icon image to be displayed
+     */
+    void setIconImage(Image image);
+
+    /**
+     * Makes window top-most if value is true,
+     * non-topmost(normal) otherwise.
+     */
+    void setAlwaysOnTop(boolean value);
+
+    /**
+     * Set desired [top-level] window bounds when being in maximized state.
+     * Fields set to Integer.MAX_VALUE are ignored[system-supplied values are
+     * used instead]
+     */
+    void setMaximizedBounds(Rectangle bounds);
+
+    /**
+     * Get absolute position on the screen
+     */
+    Point getScreenPos();
+
+    /**
+     * Set a window "packed" flag:
+     * the flag indicates that if insets change
+     * client area shouldn't be resized, but frame
+     * must be resized instead
+     */
+    void setPacked(boolean packed);
+    
+    /**
+     * Make window an "input method window" by setting
+     * special window style, e. g. small title bar, no
+     * close, minimize/maximize buttons. For internal
+     * use by input method framework.
+     *
+     */
+    void setIMStyle();
+
+    MultiRectArea getObscuredRegion(Rectangle part);
+}
diff --git a/awt/org/apache/harmony/awt/wtk/ShutdownThread.java b/awt/org/apache/harmony/awt/wtk/ShutdownThread.java
new file mode 100644
index 0000000..701eb46
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/ShutdownThread.java
@@ -0,0 +1,83 @@
+/*
+ *  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 Michael Danilov, Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+public final class ShutdownThread extends Thread {
+    
+    public static final class Watchdog {
+    }
+
+    public ShutdownThread() {
+        setName("AWT-Shutdown"); //$NON-NLS-1$
+        setDaemon(false);
+    }
+    
+    private boolean shouldStop = false;
+
+    @Override
+    public void run() {
+        synchronized (this) {
+            notifyAll(); // synchronize the startup
+
+            while (true) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                }
+
+                if (shouldStop) {
+                    notifyAll(); // synchronize the shutdown
+                    return;
+                }
+            }
+        }
+    }
+
+    @Override
+    public void start() {
+        synchronized (this) {
+            super.start();
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                // awt.26=Shutdown thread was interrupted while starting
+                throw new RuntimeException(
+                        Messages.getString("awt.26")); //$NON-NLS-1$
+            }
+        }
+    }
+
+    public void shutdown() {
+        synchronized (this) {
+            shouldStop = true;
+            notifyAll();
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                // awt.27=Shutdown thread was interrupted while stopping
+                throw new RuntimeException(
+                        Messages.getString("awt.27")); //$NON-NLS-1$
+            }
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/wtk/ShutdownWatchdog.java b/awt/org/apache/harmony/awt/wtk/ShutdownWatchdog.java
new file mode 100644
index 0000000..6efa519
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/ShutdownWatchdog.java
@@ -0,0 +1,86 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+/**
+ * Shutdown Watchdog
+ */
+public final class ShutdownWatchdog {
+    
+    private boolean nativeQueueEmpty = true;
+    private boolean awtQueueEmpty = true;
+    private boolean windowListEmpty = true;
+
+    private boolean forcedShutdown = false;
+    
+    private ShutdownThread thread;
+
+    public synchronized void setNativeQueueEmpty(boolean empty) {
+        nativeQueueEmpty = empty;
+        checkShutdown();
+    }
+
+    public synchronized void setAwtQueueEmpty(boolean empty) {
+        awtQueueEmpty = empty;
+        checkShutdown();
+    }
+
+    public synchronized void setWindowListEmpty(boolean empty) {
+        windowListEmpty = empty;
+        checkShutdown();
+    }
+    
+    public synchronized void forceShutdown() {
+        forcedShutdown = true;
+        shutdown();
+    }
+    
+    public synchronized void start() {
+        keepAlive();
+    }
+
+    private void checkShutdown() {
+        if (canShutdown()) {
+            shutdown();
+        } else {
+            keepAlive();
+        }
+    }
+
+    private boolean canShutdown() {
+        return (nativeQueueEmpty && awtQueueEmpty && windowListEmpty) ||
+                forcedShutdown;
+    }
+
+    private void keepAlive() {
+        if (thread == null) {
+            thread = new ShutdownThread();
+            thread.start();
+        }
+    }
+
+    private void shutdown() {
+        if (thread != null) {
+            thread.shutdown();
+            thread = null;
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/awt/wtk/Synchronizer.java b/awt/org/apache/harmony/awt/wtk/Synchronizer.java
new file mode 100644
index 0000000..3eeaa0b
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/Synchronizer.java
@@ -0,0 +1,200 @@
+/*
+ *  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 Mikhail Danilov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.util.Hashtable;
+import java.util.LinkedList;
+
+import org.apache.harmony.awt.internal.nls.Messages;
+
+/**
+ * Class synchronizer is to protect AWT state integrity in multithreading environment.
+ * It is supposed to have a child class per native platform.
+ * The only instance is created on the first use of one of the core AWT classes.
+ * Registers WTK on the dispatch thread startup.
+ * It is just a special kind of mutex.
+ *
+ */
+
+public class Synchronizer {
+    //TODO: think about java.util.concurrent use for faster blocking/awaking operations
+    //TODO: think about all synchronized methods. Is there need to synchronize everything?
+
+    /**
+     * This field holds the counter of lock operation.
+     * To free synchronizer unlock method must be called $acquestCounter times.
+     * Equals to 0 when synchronizer is free.
+     */
+    protected int acquestCounter;
+
+    /**
+     * This field holds the owner of synchronizer.
+     * Owner of synchronizer is a last thread that successfully locked synchronizer and
+     * still havn't freed it. Equals to null when synchronizer is free.
+     */
+    protected Thread owner;
+
+    /**
+     * This field holds the wait queue.
+     * Wait queue is a queue where thread wait for synchronizer access.
+     * Empty when synchronizer is free.
+     */
+    protected final LinkedList<Thread> waitQueue = new LinkedList<Thread>();
+
+    /**
+     * The event dispatch thread
+     */
+    protected Thread dispatchThread;
+
+    private final Hashtable<Thread, Integer> storedStates = new Hashtable<Thread, Integer>();
+
+    /**
+     * Acquire the lock for this synchronizer. Nested lock is supported.
+     * If the mutex is already locked by another thread, the current thread will be put
+     * into wait queue until the lock becomes available.
+     * All user threads are served in FIFO order. Dispatch thread has higher priority.
+     * Supposed to be used in Toolkit.lockAWT() only.
+     */
+    public void lock() {
+        synchronized (this) {
+            Thread curThread = Thread.currentThread();
+
+            if (acquestCounter == 0) {
+                acquestCounter = 1;
+                owner = curThread;
+            } else {
+                if (owner == curThread) {
+                    acquestCounter++;
+                } else {
+                    if (curThread == dispatchThread) {
+                        waitQueue.addFirst(curThread);
+                    } else {
+                        waitQueue.addLast(curThread);
+                    }
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                        if (owner != curThread) {
+                            waitQueue.remove(curThread);
+                            // awt.1F=Waiting for resource access thread interrupted not from unlock method.
+                            throw new RuntimeException(Messages
+                                    .getString("awt.1F")); //$NON-NLS-1$
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Release the lock for this synchronizer.
+     * If wait queue is not empty the first waiting thread acquires the lock.
+     * Supposed to be used in Toolkit.unlockAWT() only.
+     */
+    public void unlock() {
+        synchronized (this) {
+            if (acquestCounter == 0) {
+                // awt.20=Can't unlock not locked resource.
+                throw new RuntimeException(Messages.getString("awt.20")); //$NON-NLS-1$
+            }
+            if (owner != Thread.currentThread()) {
+                // awt.21=Not owner can't unlock resource.
+                throw new RuntimeException(Messages.getString("awt.21")); //$NON-NLS-1$
+            }
+
+            acquestCounter--;
+            if (acquestCounter == 0) {
+                if (waitQueue.size() > 0) {
+                    acquestCounter = 1;
+                    owner = waitQueue.removeFirst();
+                    owner.interrupt();
+                } else {
+                    owner = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * Stores state of this synchronizer and frees it.
+     * Supposed to be used in Toolkit.unsafeInvokeAndWaitUnderAWTLock() only in pair with
+     * lockAndRestoreState().
+     * Do not call it directly.
+     */
+    public void storeStateAndFree() {
+        synchronized (this) {
+            Thread curThread = Thread.currentThread();
+
+            if (owner != curThread) {
+                // awt.22=Not owner can't free resource.
+                throw new RuntimeException(Messages.getString("awt.22")); //$NON-NLS-1$
+            }
+            if (storedStates.containsKey(curThread)) {
+                // awt.23=One thread can't store state several times in a row.
+                throw new RuntimeException(Messages.getString("awt.23")); //$NON-NLS-1$
+            }
+
+            storedStates.put(curThread, new Integer(acquestCounter));
+            acquestCounter = 1;
+            unlock();
+        }
+    }
+
+    /**
+     * Locks this synchronizer and restores it's state.
+     * Supposed to be used in Toolkit.unsafeInvokeAndWaitUnderAWTLock() only in pair with
+     * storeStateAndFree().
+     * Do not call it directly.
+     */
+    public void lockAndRestoreState() {
+        synchronized (this) {
+            Thread curThread = Thread.currentThread();
+
+            if (owner == curThread) {
+                // awt.24=Owner can't overwrite resource state. Lock operations may be lost.
+                throw new RuntimeException(
+                        Messages.getString("awt.24")); //$NON-NLS-1$
+            }
+            if (!storedStates.containsKey(curThread)) {
+                // awt.25=No state stored for current thread.
+                throw new RuntimeException(Messages.getString("awt.25")); //$NON-NLS-1$
+            }
+
+            lock();
+            acquestCounter = storedStates.get(curThread).intValue();
+            storedStates.remove(curThread);
+        }
+    }
+
+    /**
+     * Sets references to WTK and event dispatch thread.
+     * Called on toolkit startup.
+     *
+     * @param wtk - reference to WTK instance
+     * @param dispatchThread - reference to event dispatch thread
+     */
+    public void setEnvironment(WTK wtk, Thread dispatchThread) {
+        synchronized (this) {
+            this.dispatchThread = dispatchThread;
+        }
+    }
+
+}
diff --git a/awt/org/apache/harmony/awt/wtk/SystemProperties.java b/awt/org/apache/harmony/awt/wtk/SystemProperties.java
new file mode 100644
index 0000000..6b59f0e
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/SystemProperties.java
@@ -0,0 +1,59 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Font;
+import java.awt.font.TextAttribute;
+import java.awt.im.InputMethodHighlight;
+import java.util.Map;
+
+/**
+ * NativeProperties
+ */
+
+public interface SystemProperties {
+
+    /**
+     * Get current value of a system color
+     * @param index - one of java.awt.SystemColor constants
+     * @return ARGB value of requested system color
+     */
+    int getSystemColorARGB(int index);
+
+    /**
+     * Get default font for GUI elements such as menus and buttons
+     * @return the font object
+     */
+    Font getDefaultFont();
+    
+    /**
+     * Fill the given Map with system properties
+     */
+    void init(Map<String, ?> desktopProperties);
+
+    /**
+     * Fills the given map with system-dependent visual text
+     * attributes for the abstract description 
+     * of the given input method highlight
+     * @see java.awt.Toolkit.mapInputMethodHighlight()
+     */
+    void mapInputMethodHighlight(InputMethodHighlight highlight, Map<TextAttribute, ?> map);
+}
diff --git a/awt/org/apache/harmony/awt/wtk/WTK.java b/awt/org/apache/harmony/awt/wtk/WTK.java
new file mode 100644
index 0000000..4162fbd
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/WTK.java
@@ -0,0 +1,61 @@
+/*
+ *  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 Pavel Dolgov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.GraphicsDevice;
+
+
+public abstract class WTK {
+
+    public abstract GraphicsFactory getGraphicsFactory();
+    public abstract NativeEventQueue getNativeEventQueue();
+    public abstract WindowFactory getWindowFactory();
+
+    /**
+     * Returns platform specific implementation of the interface
+     * org.apache.harmony.awt.wtk.CursorFactory.
+     * @return implementation of CursorFactory
+     */
+    public abstract CursorFactory getCursorFactory();
+
+    /**
+     * Returns platform specific implementation of the interface
+     * org.apache.harmony.awt.wtk.NativeMouseInfo.
+     * @return implementation of NativeMouseInfo
+     */
+    public abstract NativeMouseInfo getNativeMouseInfo();
+
+    public abstract SystemProperties getSystemProperties();
+
+    /**
+     * Returns platform specific implementation of the interface
+     * org.apache.harmony.awt.wtk.NativeRobot.
+     * @return implementation of NativeRobot
+     */
+    public abstract NativeRobot getNativeRobot(GraphicsDevice screen);
+    
+    /**
+     * Returns platform specific implementation of the abstract
+     * class org.apache.harmony.awt.wtk.NativeIM.
+     * @return implementation of NativeIM
+     */
+    public abstract NativeIM getNativeIM();
+}
diff --git a/awt/org/apache/harmony/awt/wtk/WindowFactory.java b/awt/org/apache/harmony/awt/wtk/WindowFactory.java
new file mode 100644
index 0000000..23604da
--- /dev/null
+++ b/awt/org/apache/harmony/awt/wtk/WindowFactory.java
@@ -0,0 +1,85 @@
+/*
+ *  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 Mikhail Danilov
+ * @version $Revision$
+ */
+package org.apache.harmony.awt.wtk;
+
+import java.awt.Dimension;
+import java.awt.Point;
+
+/**
+ * Provides factory for NativeWindow
+ */
+public interface WindowFactory {
+    /**
+     * Creates and returns NativeWindow with desired
+     * creation params
+     *
+     * @param p - initial window properties
+     * @return created window
+     */
+    NativeWindow createWindow(CreationParams p);
+    /**
+     * Create NativeWindow instance connected to existing native resource
+     * @param nativeWindowId - id of existing window
+     * @return created NativeWindow instance
+     */
+    NativeWindow attachWindow(long nativeWindowId);
+    /**
+     * Returns NativeWindow instance if created by this instance of
+     * WindowFactory, otherwise null
+     *
+     * @param id - HWND on Windows xwindow on X
+     * @return NativeWindow or null if unknown
+     */
+    NativeWindow getWindowById(long id);
+    /**
+     * Returns NativeWindow instance of the top-level window
+     * that contains a specified point and was
+     * created by this instance of WindowFactory
+     * @param p - Point to check
+     * @return NativeWindow or null if the point is
+     * not within a window created by this WindowFactory
+     */
+    NativeWindow getWindowFromPoint(Point p);
+
+    /**
+     * Returns whether native system supports the state for windows.
+     * This method tells whether the UI concept of, say, maximization or iconification is supported.
+     * It will always return false for "compound" states like Frame.ICONIFIED|Frame.MAXIMIZED_VERT.
+     * In other words, the rule of thumb is that only queries with a single frame state
+     * constant as an argument are meaningful.
+     *
+     * @param state - one of named frame state constants.
+     * @return true is this frame state is supported by this Toolkit implementation, false otherwise.
+     */
+    boolean isWindowStateSupported(int state);
+
+    /**
+     * @see org.apache.harmony.awt.ComponentInternals
+     */
+    void setCaretPosition(int x, int y);
+
+    /**
+     * Request size of arbitrary native window
+     * @param id - window ID
+     * @return window size
+     */
+    Dimension getWindowSizeById(long id);
+}
\ No newline at end of file
diff --git a/awt/org/apache/harmony/beans/internal/nls/Messages.java b/awt/org/apache/harmony/beans/internal/nls/Messages.java
new file mode 100644
index 0000000..727c757
--- /dev/null
+++ b/awt/org/apache/harmony/beans/internal/nls/Messages.java
@@ -0,0 +1,132 @@
+/* 
+ * 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.
+ */
+
+/*
+ * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
+ * All changes made to this file manually will be overwritten 
+ * if this tool runs again. Better make changes in the template file.
+ */
+
+package org.apache.harmony.beans.internal.nls;
+
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.apache.harmony.kernel.vm.VM;
+import org.apache.harmony.luni.util.MsgHelp;
+
+/**
+ * This class retrieves strings from a resource bundle and returns them,
+ * formatting them with MessageFormat when required.
+ * <p>
+ * It is used by the system classes to provide national language support, by
+ * looking up messages in the <code>
+ *    org.apache.harmony.beans.internal.nls.messages
+ * </code>
+ * resource bundle. Note that if this file is not available, or an invalid key
+ * is looked up, or resource bundle support is not available, the key itself
+ * will be returned as the associated message. This means that the <em>KEY</em>
+ * should a reasonable human-readable (english) string.
+ * 
+ */
+public class Messages {
+
+    private static final String sResource =
+        "org.apache.harmony.beans.internal.nls.messages"; //$NON-NLS-1$
+
+    /**
+     * Retrieves a message which has no arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg) {
+        return MsgHelp.getString(sResource, msg);
+    }
+
+    /**
+     * Retrieves a message which takes 1 argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            Object the object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg) {
+        return getString(msg, new Object[] { arg });
+    }
+
+    /**
+     * Retrieves a message which takes 1 integer argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            int the integer to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, int arg) {
+        return getString(msg, new Object[] { Integer.toString(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 1 character argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            char the character to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, char arg) {
+        return getString(msg, new Object[] { String.valueOf(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 2 arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg1
+     *            Object an object to insert in the formatted output.
+     * @param arg2
+     *            Object another object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg1, Object arg2) {
+        return getString(msg, new Object[] { arg1, arg2 });
+    }
+
+    /**
+     * Retrieves a message which takes several arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param args
+     *            Object[] the objects to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object[] args) {
+        return MsgHelp.getString(sResource, msg, args);
+    }
+}
diff --git a/awt/org/apache/harmony/beans/internal/nls/messages.properties b/awt/org/apache/harmony/beans/internal/nls/messages.properties
new file mode 100644
index 0000000..72b1c8c
--- /dev/null
+++ b/awt/org/apache/harmony/beans/internal/nls/messages.properties
@@ -0,0 +1,103 @@
+# 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.
+# 
+
+# messages for EN locale
+beans.00=no getter for {0} property
+beans.01=no property for name {0} is found
+beans.02=in DefaultPersistenceDelegate.mutatesTo() {0} : {1}
+beans.03=Target Bean class is null
+beans.04=bad property name
+beans.05=Modifier for setter method should be public.
+beans.06=Number of parameters in setter method is not equal to 1.
+beans.07=Parameter type in setter method does not corresponds to predefined.
+beans.08=Number of parameters in getter method is not equal to 0.
+beans.09=Parameter type in getter method does not corresponds to predefined.
+beans.0A=Modifier for getter method should be public.
+beans.0B=Exception in command execution
+beans.0C=source is null
+beans.0D=Error in expression: {0}
+beans.0E=Changes are null
+beans.0F=The new BeanContext can not be set
+beans.10=no node is found for statement with target = {0}
+beans.11=no getter for property {0} found
+beans.12=cannot access property {0} getter
+beans.13=no setter for property {0} found
+beans.14=Exception while finding property descriptor
+beans.15=The listener is null
+beans.16=The provider is null
+beans.17=The child is null
+beans.18=The requestor is null
+beans.19=The service class is null
+beans.1A=The service selector is null
+beans.1B=The service is null
+beans.1C=The event is null
+beans.1D=bean is null
+beans.1E=Illegal class name: {0}
+beans.1F=Method not found: get{0}
+beans.20=Method not found: set{0}
+beans.21=Modifier for indexed getter method should be public.
+beans.22=Number of parameters in getter method is not equal to 1.
+beans.23=Parameter in indexed getter method is not of integer type.
+beans.24=Parameter type in indexed getter method does not correspond to predefined.
+beans.25=Modifier for indexed setter method should be public.
+beans.26=Number of parameters in indexed setter method is not equal to 2.
+beans.27=First parameter type in indexed setter method should be int.
+beans.28=Second parameter type in indexed setter method does not corresponds to predefined.
+beans.29=Membership listener is null
+beans.2A=Target child can not be null
+beans.2B=Resource name can not be null
+beans.2C=The child can not be null
+beans.2D=Invalid resource
+beans.2E=PropertyVetoException was thrown while removing a child: {0}; Original error message:{1}
+beans.2F=Target child is null
+beans.30=PropertyVetoException was thrown while adding a child: {0}; Original error message:{1}
+beans.31=No valid method {0} for {1} found.
+beans.32=Cannot acquire event type from {0} listener.
+beans.33={0} does not return <void>
+beans.34={0} should have a single input parameter
+beans.35=Single parameter does not match to {0} class
+beans.36=No input params are allowed for getListenerMethod
+beans.37=Return type of getListenerMethod is not an array of listeners
+beans.38=Add and remove methods are not available
+beans.39=Cannot generate event set descriptor for name {0}.
+beans.3A=Event type with name {0} is not found.
+beans.3B=skipping expression {0}...
+beans.3C=Unknown method name for array
+beans.3D=First parameter in array getter(setter) is not of Integer type
+beans.3E=Illegal number of arguments in array getter
+beans.3F=Illegal number of arguments in array setter
+beans.40=No constructor for class {0} found
+beans.41=No method with name {0} is found
+beans.42=target is not generated: classname {0} is not found
+beans.43=Cannot convert {0} to char
+beans.44=for property {0} no getter(setter) is found
+beans.45=method name is not generated: error in getMethodName()
+beans.46=Not a valid child
+beans.47=Unable to instantiate property editor
+beans.48=Property editor is not assignable from the PropertyEditor interface
+beans.49=Child cannot implement both BeanContextChild and BeanContextProxy
+beans.4A=newInstance is null
+beans.4B=type is null
+beans.4C=encoder is null
+beans.4D=Invalid method call
+beans.4E=stopClass is not ancestor of beanClass
+beans.4F=search path is null
+beans.50=not an indexed property
+beans.51=Listener method {0} should have parameter of type {1}
+beans.52=listenerMethodName(s) is null
+beans.53=eventSetName is null
+beans.54=listenerType is null
+beans.55=Method is null
diff --git a/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java b/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java
new file mode 100644
index 0000000..498e1bb
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java
@@ -0,0 +1,124 @@
+/* 
+ * 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.
+ */
+
+/*
+ * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
+ * All changes made to this file manually will be overwritten 
+ * if this tool runs again. Better make changes in the template file.
+ */
+
+package org.apache.harmony.x.imageio.internal.nls;
+
+import org.apache.harmony.luni.util.MsgHelp;
+
+/**
+ * This class retrieves strings from a resource bundle and returns them,
+ * formatting them with MessageFormat when required.
+ * <p>
+ * It is used by the system classes to provide national language support, by
+ * looking up messages in the <code>
+ *    org.apache.harmony.x.imageio.internal.nls.messages
+ * </code>
+ * resource bundle. Note that if this file is not available, or an invalid key
+ * is looked up, or resource bundle support is not available, the key itself
+ * will be returned as the associated message. This means that the <em>KEY</em>
+ * should a reasonable human-readable (english) string.
+ * 
+ */
+public class Messages {
+
+    private static final String sResource =
+        "org.apache.harmony.x.imageio.internal.nls.messages"; //$NON-NLS-1$
+
+    /**
+     * Retrieves a message which has no arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg) {
+        return MsgHelp.getString(sResource, msg);
+    }
+
+    /**
+     * Retrieves a message which takes 1 argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            Object the object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg) {
+        return getString(msg, new Object[] { arg });
+    }
+
+    /**
+     * Retrieves a message which takes 1 integer argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            int the integer to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, int arg) {
+        return getString(msg, new Object[] { Integer.toString(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 1 character argument.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg
+     *            char the character to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, char arg) {
+        return getString(msg, new Object[] { String.valueOf(arg) });
+    }
+
+    /**
+     * Retrieves a message which takes 2 arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param arg1
+     *            Object an object to insert in the formatted output.
+     * @param arg2
+     *            Object another object to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object arg1, Object arg2) {
+        return getString(msg, new Object[] { arg1, arg2 });
+    }
+
+    /**
+     * Retrieves a message which takes several arguments.
+     * 
+     * @param msg
+     *            String the key to look up.
+     * @param args
+     *            Object[] the objects to insert in the formatted output.
+     * @return String the message for that key in the system message bundle.
+     */
+    static public String getString(String msg, Object[] args) {
+        return MsgHelp.getString(sResource, msg, args);
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties b/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties
new file mode 100644
index 0000000..8a49dd8
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties
@@ -0,0 +1,18 @@
+# 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.
+# 
+
+# messages for EN locale
+imageio.1=Wrong bitDepth-numBands composition
\ No newline at end of file
diff --git a/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java b/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java
new file mode 100644
index 0000000..caeefdd
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java
@@ -0,0 +1,94 @@
+/*
+ *  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 org.apache.harmony.x.imageio.metadata;
+
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.imageio.metadata.IIOMetadataFormat;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+
+public class IIOMetadataUtils {
+    private IIOMetadataUtils() {} 
+
+    public static IIOMetadataFormat instantiateMetadataFormat(
+            String formatName, boolean standardFormatSupported,
+            String nativeMetadataFormatName, String nativeMetadataFormatClassName,
+            String [] extraMetadataFormatNames, String [] extraMetadataFormatClassNames
+    ) {
+        if (formatName == null) {
+            throw new IllegalArgumentException("formatName == null!");
+        }
+        if (formatName.equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {
+            if (standardFormatSupported) {
+                return IIOMetadataFormatImpl.getStandardFormatInstance();
+            }
+        }
+
+        String className = null;
+
+        if (formatName.equals(nativeMetadataFormatName)) {
+            className = nativeMetadataFormatClassName;
+        } else if (extraMetadataFormatNames != null) {
+            for (int i = 0; i < extraMetadataFormatNames.length; i++) {
+                if (formatName.equals(extraMetadataFormatNames[i])) {
+                    className = extraMetadataFormatClassNames[i];
+                    break;
+                }
+            }
+        }
+
+        if (className == null) {
+            throw new IllegalArgumentException("Unsupported format name");
+        }
+
+        // Get the context class loader and try to use it first
+        ClassLoader contextClassloader = AccessController.doPrivileged(
+                new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
+                        return Thread.currentThread().getContextClassLoader();
+                    }
+        });
+
+        Class cls;
+
+        try {
+            cls = Class.forName(className, true, contextClassloader);
+        } catch (ClassNotFoundException e) {
+            try {
+                // Use current class loader
+                cls = Class.forName(className);
+            } catch (ClassNotFoundException e1) {
+                throw new IllegalStateException ("Can't obtain format");
+            }
+        }
+
+        try {
+            //???AWT:
+            //Method getInstance = cls.getMethod("getInstance");
+            //return (IIOMetadataFormat) getInstance.invoke(null);
+            return null;
+        } catch (Exception e) {
+            IllegalStateException e1 = new IllegalStateException("Can't obtain format");
+            e1.initCause(e); // Add some details to the message
+            throw e1;
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java
new file mode 100644
index 0000000..051f906
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.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.
+ */
+/**
+ * @author Rustem Rafikov
+ * @version $Revision: 1.2 $
+ */
+package org.apache.harmony.x.imageio.plugins.jpeg;
+
+import javax.imageio.stream.ImageInputStream;
+
+import org.apache.harmony.awt.gl.image.DecodingImageSource;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * This allows usage of the java2d jpegdecoder with ImageInputStream in
+ * the JPEGImageReader. Temporary, only to make JPEGImageReader#read(..)
+ * working.
+ *
+ */
+public class IISDecodingImageSource extends DecodingImageSource {
+
+    private final InputStream is;
+
+    public IISDecodingImageSource(ImageInputStream iis) {
+        is = new IISToInputStreamWrapper(iis);
+    }
+
+    @Override
+    protected boolean checkConnection() {
+        return true;
+    }
+
+    @Override
+    protected InputStream getInputStream() {
+        return is;
+    }
+
+    static class IISToInputStreamWrapper extends InputStream {
+
+        private ImageInputStream input;
+
+        public IISToInputStreamWrapper(ImageInputStream input) {
+            this.input=input;
+        }
+
+        @Override
+        public int read() throws IOException {
+            return input.read();
+        }
+
+        @Override
+        public int read(byte[] b) throws IOException {
+            return input.read(b);
+        }
+
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            return input.read(b, off, len);
+        }
+
+        @Override
+        public long skip(long n) throws IOException {
+            return input.skipBytes(n);
+        }
+
+        @Override
+        public boolean markSupported() {
+        	return true;  // This is orig
+        	
+            // ???AWT: FIXME
+        	// This is an error in Harmony. Not all input streams
+        	// have mark support and it is not ok to just return true. 
+        	// There should be an input.markSupported(). However, if 
+        	// this call returns false, nothing works anymore.
+        	
+        	// The backside is that BitmapFactory uses a call to markSupport()
+        	// to find out if it needs to warp the stream in a
+        	// BufferedInputStream to get mark support, and this fails!
+        	
+        	// Currently, the hack is in BitmapFactory, where we always
+        	// wrap the stream in a BufferedInputStream.
+        }
+
+        @Override
+        public void mark(int readlimit) {
+            input.mark();
+        }
+
+        @Override
+        public void reset() throws IOException {
+            input.reset();
+        }
+
+        @Override
+        public void close() throws IOException {
+            input.close();
+        }
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java
new file mode 100644
index 0000000..067a825
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java
@@ -0,0 +1,44 @@
+/*
+ *  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 org.apache.harmony.x.imageio.plugins.jpeg;
+
+public class JPEGConsts {
+
+    private JPEGConsts() {}
+
+    public static final int SOI = 0xD8;
+
+    //-- IJG (Independed JPEG Group) color spaces
+    public static final int JCS_UNKNOW = 0;
+    public static final int JCS_GRAYSCALE = 1;
+    public static final int JCS_RGB = 2;
+    public static final int JCS_YCbCr = 3;
+    public static final int JCS_CMYK = 4;
+    public static final int JCS_YCC = 5;
+    public static final int JCS_RGBA = 6;
+    public static final int JCS_YCbCrA = 7;
+    public static final int JCS_YCCA = 10;
+    public static final int JCS_YCCK = 11;
+
+    public static int[][] BAND_OFFSETS = {{}, {0}, {0, 1}, {0, 1, 2}, {0, 1, 2, 3}};
+
+    public static final float DEFAULT_JPEG_COMPRESSION_QUALITY = 0.75f;
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java
new file mode 100644
index 0000000..110ed23
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java
@@ -0,0 +1,126 @@
+/*
+ *  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.4 $
+ */
+package org.apache.harmony.x.imageio.plugins.jpeg;
+
+
+import javax.imageio.ImageReader;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.plugins.jpeg.JPEGImageReadParam;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageReaderSpi;
+
+import org.apache.harmony.awt.gl.image.DecodingImageSource;
+import org.apache.harmony.awt.gl.image.OffscreenImage;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.awt.image.BufferedImage;
+
+/**
+ * This implementation uses org.apache.harmony.awt.gl.image.JpegDecoder to read
+ * an image. The only implemented method is read(..);
+ *
+ * TODO: Implements generic decoder to be used by javad2 and imageio
+ *
+ * @see org.apache.harmony.awt.gl.image.JpegDecoder
+ * @see org.apache.harmony.x.imageio.plugins.jpeg.IISDecodingImageSource
+ */
+public class JPEGImageReader extends ImageReader {
+
+    ImageInputStream iis;
+
+    public JPEGImageReader(ImageReaderSpi imageReaderSpi) {
+        super(imageReaderSpi);
+    }
+
+    @Override
+    public int getHeight(int i) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public int getWidth(int i) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public int getNumImages(boolean b) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public Iterator<ImageTypeSpecifier> getImageTypes(int i) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public IIOMetadata getStreamMetadata() throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public IIOMetadata getImageMetadata(int i) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public BufferedImage read(int i, ImageReadParam imageReadParam) throws IOException {
+        if (iis == null) {
+            throw new IllegalArgumentException("input stream == null");
+        }
+
+        DecodingImageSource source = new IISDecodingImageSource(iis);
+        OffscreenImage image = new OffscreenImage(source);
+        source.addConsumer(image);
+        source.load();
+        // The interrupted flag should be cleared because ImageDecoder interrupts
+        // current thread while decoding. The same technique is used in
+        // ImageLoader#run(). Another solution can be to create
+        // a separate decoding thread. However, decoder keeps its own pool
+        // of threads so creating a new thread will be just a waste of resources.
+        Thread.interrupted();
+        return image.getBufferedImage();
+    }
+
+    @Override
+    public BufferedImage read(int i) throws IOException {
+        return read(i, null);
+    }
+
+    @Override
+    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
+        super.setInput(input, seekForwardOnly, ignoreMetadata);
+        iis = (ImageInputStream) input;
+    }
+
+    @Override
+    public ImageReadParam getDefaultReadParam() {
+        return new JPEGImageReadParam();
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java
new file mode 100644
index 0000000..c719ce7
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java
@@ -0,0 +1,86 @@
+/*
+ *  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 org.apache.harmony.x.imageio.plugins.jpeg;
+
+import java.io.IOException;
+import java.util.Locale;
+import javax.imageio.ImageReader;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ServiceRegistry;
+import javax.imageio.stream.ImageInputStream;
+
+public class JPEGImageReaderSpi extends ImageReaderSpi {
+
+    public JPEGImageReaderSpi() {
+        super(JPEGSpiConsts.vendorName, JPEGSpiConsts.version,
+                JPEGSpiConsts.names, JPEGSpiConsts.suffixes,
+                JPEGSpiConsts.MIMETypes, JPEGSpiConsts.readerClassName,
+                STANDARD_INPUT_TYPE, JPEGSpiConsts.writerSpiNames,
+                JPEGSpiConsts.supportsStandardStreamMetadataFormat,
+                JPEGSpiConsts.nativeStreamMetadataFormatName,
+                JPEGSpiConsts.nativeStreamMetadataFormatClassName,
+                JPEGSpiConsts.extraStreamMetadataFormatNames,
+                JPEGSpiConsts.extraStreamMetadataFormatClassNames,
+                JPEGSpiConsts.supportsStandardImageMetadataFormat,
+                JPEGSpiConsts.nativeImageMetadataFormatName,
+                JPEGSpiConsts.nativeImageMetadataFormatClassName,
+                JPEGSpiConsts.extraImageMetadataFormatNames,
+                JPEGSpiConsts.extraImageMetadataFormatClassNames);
+    }
+
+
+    @Override
+    public boolean canDecodeInput(Object source) throws IOException {
+        ImageInputStream markable = (ImageInputStream) source;
+        try {
+            markable.mark();
+
+            byte[] signature = new byte[3];
+            markable.seek(0);
+            markable.read(signature, 0, 3);
+            markable.reset();
+
+            if ((signature[0] & 0xFF) == 0xFF &&
+                    (signature[1] & 0xFF) == JPEGConsts.SOI &&
+                    (signature[2] & 0xFF) == 0xFF) { // JPEG
+                return true;
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    @Override
+    public ImageReader createReaderInstance(Object extension) throws IOException {
+        return new JPEGImageReader(this);
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "DRL JPEG decoder";
+    }
+
+    @Override
+    public void onRegistration(ServiceRegistry registry, Class<?> category) {
+        // super.onRegistration(registry, category);
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java
new file mode 100644
index 0000000..ae3e876
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java
@@ -0,0 +1,402 @@
+/*
+ *  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 org.apache.harmony.x.imageio.plugins.jpeg;
+
+import com.android.internal.awt.ImageOutputStreamWrapper;
+
+import javax.imageio.ImageWriter;
+import javax.imageio.IIOImage;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.metadata.IIOMetadata;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap.CompressFormat;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.awt.image.*;
+import java.awt.*;
+import java.awt.color.ColorSpace;
+
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+public class JPEGImageWriter extends ImageWriter {
+
+    // /* ???AWT: Debugging
+    private static final boolean DEBUG = false;
+    private static Bitmap bm;
+    public static Bitmap getBitmap() {
+        return bm;
+    }
+    private static BufferedImage bufImg;
+    public static BufferedImage getBufImage() {
+        return bufImg;
+    }
+    static private RenderedImage renImg;
+    static public RenderedImage getRenImage() {
+        return renImg;
+    }
+    // */
+    
+    private long cinfo;
+    private RenderedImage image;
+    private Raster sourceRaster;
+    private WritableRaster scanRaster;
+    private int srcXOff = 0;
+    private int srcYOff = 0;
+    private int srcWidth;
+    private int srcHeight;
+
+    //-- y step for image subsampling
+    private int deltaY = 1;
+    //-- x step for image subsampling
+    private int deltaX = 1;
+
+    private ImageOutputStream ios;
+
+    public JPEGImageWriter(ImageWriterSpi imageWriterSpi) {
+        super(imageWriterSpi);
+        //???AWT: cinfo = initCompressionObj();
+        cinfo = System.currentTimeMillis();
+    }
+
+    static {
+        //???AWT
+        /*
+        System.loadLibrary("jpegencoder");
+        initWriterIds(ImageOutputStream.class);
+        */
+    }
+
+    @Override
+    public void write(IIOMetadata iioMetadata, IIOImage iioImage, ImageWriteParam param)
+            throws IOException {
+
+        if (ios == null) {
+            throw new IllegalArgumentException("ios == null");
+        }
+        if (iioImage == null) {
+            throw new IllegalArgumentException("Image equals null");
+        }
+
+        RenderedImage img = null;
+        if (!iioImage.hasRaster()) {
+            img = iioImage.getRenderedImage();
+            if (img instanceof BufferedImage) {
+                sourceRaster = ((BufferedImage) img).getRaster();
+            } else {
+                sourceRaster = img.getData();
+            }
+        } else {
+            sourceRaster = iioImage.getRaster();
+        }
+        
+        // AWT???: Debugging
+        if (DEBUG) {
+            if( img==null ) {
+                System.out.println("****J: Image is NULL");
+            } else {
+                renImg = img;
+                bufImg = (BufferedImage)img;
+            }
+        }
+
+        int numBands = sourceRaster.getNumBands();
+        int sourceIJGCs = img == null ? JPEGConsts.JCS_UNKNOW : getSourceCSType(img);
+
+        srcWidth = sourceRaster.getWidth();
+        srcHeight = sourceRaster.getHeight();
+
+        int destWidth = srcWidth;
+        int destHeight = srcHeight;
+
+        boolean progressive = false;
+         
+        if (param != null) {
+            Rectangle reg = param.getSourceRegion();
+            if (reg != null) {
+                srcXOff = reg.x;
+                srcYOff = reg.y;
+
+                srcWidth = reg.width + srcXOff > srcWidth
+                        ? srcWidth - srcXOff
+                        : reg.width;
+                srcHeight = reg.height + srcYOff > srcHeight
+                        ? srcHeight - srcYOff
+                        : reg.height;
+            }
+
+            //-- TODO uncomment when JPEGImageWriteParam be implemented
+            //-- Only default progressive mode yet
+            // progressive = param.getProgressiveMode() ==  ImageWriteParam.MODE_DEFAULT;
+
+            //-- def is 1
+            deltaX = param.getSourceXSubsampling();
+            deltaY = param.getSourceYSubsampling();
+
+            //-- def is 0
+            int offsetX = param.getSubsamplingXOffset();
+            int offsetY = param.getSubsamplingYOffset();
+
+            srcXOff += offsetX;
+            srcYOff += offsetY;
+            srcWidth -= offsetX;
+            srcHeight -= offsetY;
+
+            destWidth = (srcWidth + deltaX - 1) / deltaX;
+            destHeight = (srcHeight + deltaY - 1) / deltaY;
+        }
+
+        //-- default DQTs (see JPEGQTable java doc and JPEG spec K1 & K2 tables)
+        //-- at http://www.w3.org/Graphics/JPEG/itu-t81.pdf
+        //-- Only figuring out how to set DQT in IJG library for future metadata
+        //-- support. IJG def tables are the same.
+        //JPEGQTable[] dqt = new JPEGQTable[2];
+//        int[][] dqt = null;
+//        int[][] dqt = new int[2][];
+//        dqt[0] = JPEGQTable.K1Div2Luminance.getTable();
+//        dqt[1] = JPEGQTable.K2Div2Chrominance.getTable();
+        
+        //???AWT: I think we don't need this amymore
+        /*
+        //-- using default color space
+        //-- TODO: Take destination cs from param or use default if there is no cs
+        int destIJGCs = img == null ? JPEGConsts.JCS_UNKNOW : getDestinationCSType(img);
+
+        DataBufferByte dbuffer = new DataBufferByte(numBands * srcWidth);
+
+        scanRaster = Raster.createInterleavedRaster(dbuffer, srcWidth, 1,
+                numBands * srcWidth, numBands, JPEGConsts.BAND_OFFSETS[numBands], null);
+
+        encode(dbuffer.getData(), srcWidth, destWidth, destHeight, deltaX,
+                sourceIJGCs, destIJGCs, numBands, progressive,
+                null, cinfo);
+        */
+        
+        SampleModel model = sourceRaster.getSampleModel();
+        
+        if (model instanceof SinglePixelPackedSampleModel) {
+            DataBufferInt ibuf = (DataBufferInt)sourceRaster.getDataBuffer();
+            int[] pixels = ibuf.getData();
+            
+            // Create a bitmap with the pixel
+            bm = Bitmap.createBitmap(pixels, srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
+            
+            // Use Bitmap.compress() to write the image
+            ImageOutputStreamWrapper iosw = new ImageOutputStreamWrapper(ios);
+            bm.compress(CompressFormat.JPEG, 100, iosw);
+        } else {
+            // ???AWT: Add support for other color models
+            throw new RuntimeException("Color model not supported yet");
+        }
+
+    }
+
+    @Override
+    public void dispose() {
+        super.dispose();
+        if (cinfo != 0) {
+            //???AWT: dispose(cinfo);
+            cinfo = 0;
+            ios = null;
+        }
+    }
+
+
+    public IIOMetadata getDefaultStreamMetadata(ImageWriteParam imageWriteParam) {
+        throw new UnsupportedOperationException("not supported yet");
+    }
+
+    public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageTypeSpecifier, ImageWriteParam imageWriteParam) {
+        throw new UnsupportedOperationException("not supported yet");
+    }
+
+    @Override
+    public IIOMetadata convertStreamMetadata(IIOMetadata iioMetadata, ImageWriteParam imageWriteParam) {
+        throw new UnsupportedOperationException("not supported yet");
+    }
+
+    @Override
+    public IIOMetadata convertImageMetadata(IIOMetadata iioMetadata, ImageTypeSpecifier imageTypeSpecifier, ImageWriteParam imageWriteParam) {
+        throw new UnsupportedOperationException("not supported yet");
+    }
+
+    @Override
+    public void setOutput(Object output) {
+        super.setOutput(output);
+        ios = (ImageOutputStream) output;
+        //???AWT: setIOS(ios, cinfo);
+        sourceRaster = null;
+        scanRaster = null;
+        srcXOff = 0;
+        srcYOff = 0;
+        srcWidth = 0;
+        srcHeight = 0;
+        deltaY = 1;
+    }
+
+    /**
+     * Frees resources
+     * @param structPointer
+     */
+    //???AWT: private native void dispose(long structPointer);
+
+    /**
+     * Inits methods Ids for native to java callbacks
+     * @param iosClass
+     */
+    //???AWT: private native static void initWriterIds(Class<ImageOutputStream> iosClass);
+
+    /**
+     * Inits compression objects
+     * @return pointer to the native structure
+     */
+    //???AWT: private native long initCompressionObj();
+
+    /**
+     * Sets image output stream in IJG layer
+     * @param stream
+     */
+    //???AWT: private native void setIOS(ImageOutputStream stream, long structPointer);
+
+    /**
+     * Runs encoding process.
+     *
+     * @param data image data buffer to encode
+     * @param srcWidth - source width
+     * @param width - destination width
+     * @param height destination height
+     * @param deltaX - x subsampling step
+     * @param inColorSpace - original color space
+     * @param outColorSpace - destination color space
+     * @param numBands - number of bands
+     * @param cinfo - native handler
+     * @return
+     */
+    //???AWT:
+    /*
+    private native boolean encode(byte[] data, int srcWidth,
+                                  int width, int height, int deltaX,
+                                  int inColorSpace, int outColorSpace,
+                                  int numBands, boolean progressive,
+                                  int[][] dqt,
+                                  long cinfo);
+    */
+
+    /**
+     * Callback for getting a next scanline
+     * @param scanline scan line number
+     */
+    @SuppressWarnings("unused")
+    private void getScanLine(int scanline) {
+        //-- TODO: processImageProgress in ImageWriter
+        Raster child = sourceRaster.createChild(srcXOff,
+                srcYOff + scanline * deltaY, srcWidth, 1, 0, 0, null);
+
+        scanRaster.setRect(child);
+    }
+
+    /**
+     * Maps color space types to IJG color spaces
+     * @param image
+     * @return
+     */
+    private int getSourceCSType(RenderedImage image) {
+        int type = JPEGConsts.JCS_UNKNOW;
+        ColorModel cm = image.getColorModel();
+
+        if (null == cm) {
+            return type;
+        }
+
+        if (cm instanceof IndexColorModel) {
+            throw new UnsupportedOperationException("IndexColorModel is not supported yet");
+        }
+
+        boolean hasAlpha = cm.hasAlpha();
+        ColorSpace cs = cm.getColorSpace();
+        switch(cs.getType()) {
+            case ColorSpace.TYPE_GRAY:
+                type = JPEGConsts.JCS_GRAYSCALE;
+                break;
+           case ColorSpace.TYPE_RGB:
+                type = hasAlpha ? JPEGConsts.JCS_RGBA : JPEGConsts.JCS_RGB;
+                break;
+           case ColorSpace.TYPE_YCbCr:
+                type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
+                break;
+           case ColorSpace.TYPE_3CLR:
+                 type = hasAlpha ? JPEGConsts.JCS_YCCA : JPEGConsts.JCS_YCC;
+                 break;
+           case ColorSpace.TYPE_CMYK:
+                  type = JPEGConsts.JCS_CMYK;
+                  break;
+        }
+        return type;
+    }
+
+    /**
+     * Returns destination color space.
+     * (YCbCr[A] for RGB)
+     *
+     * @param image
+     * @return
+     */
+    private int getDestinationCSType(RenderedImage image) {
+        int type = JPEGConsts.JCS_UNKNOW;
+        ColorModel cm = image.getColorModel();
+        if (null != cm) {
+            boolean hasAlpha = cm.hasAlpha();
+            ColorSpace cs = cm.getColorSpace();
+
+            switch(cs.getType()) {
+                case ColorSpace.TYPE_GRAY:
+                    type = JPEGConsts.JCS_GRAYSCALE;
+                    break;
+               case ColorSpace.TYPE_RGB:
+                    type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
+                    break;
+               case ColorSpace.TYPE_YCbCr:
+                    type = hasAlpha ? JPEGConsts.JCS_YCbCrA : JPEGConsts.JCS_YCbCr;
+                    break;
+               case ColorSpace.TYPE_3CLR:
+                     type = hasAlpha ? JPEGConsts.JCS_YCCA : JPEGConsts.JCS_YCC;
+                     break;
+               case ColorSpace.TYPE_CMYK:
+                      type = JPEGConsts.JCS_CMYK;
+                      break;
+            }
+        }
+        return type;
+    }
+
+    public ImageWriteParam getDefaultWriteParam() {
+        return new JPEGImageWriteParam(getLocale());
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java
new file mode 100644
index 0000000..b7990e0
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java
@@ -0,0 +1,56 @@
+/*
+ *  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 org.apache.harmony.x.imageio.plugins.jpeg;
+
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.ImageWriter;
+import javax.imageio.ImageTypeSpecifier;
+import java.io.IOException;
+import java.util.Locale;
+
+public class JPEGImageWriterSpi extends ImageWriterSpi {
+
+    public JPEGImageWriterSpi() {
+        super(JPEGSpiConsts.vendorName, JPEGSpiConsts.version,
+                JPEGSpiConsts.names, JPEGSpiConsts.suffixes, JPEGSpiConsts.MIMETypes,
+                JPEGSpiConsts.writerClassName, STANDARD_OUTPUT_TYPE,
+                JPEGSpiConsts.readerSpiNames, JPEGSpiConsts.supportsStandardStreamMetadataFormat /*TODO: support st. metadata format*/,
+                JPEGSpiConsts.nativeStreamMetadataFormatName, JPEGSpiConsts.nativeStreamMetadataFormatClassName,
+                JPEGSpiConsts.extraStreamMetadataFormatNames, JPEGSpiConsts.extraStreamMetadataFormatClassNames,
+                JPEGSpiConsts.supportsStandardImageMetadataFormat, JPEGSpiConsts.nativeImageMetadataFormatName, JPEGSpiConsts.nativeImageMetadataFormatClassName,
+                JPEGSpiConsts.extraImageMetadataFormatNames, JPEGSpiConsts.extraImageMetadataFormatClassNames);
+    }
+
+    @Override
+    public boolean canEncodeImage(ImageTypeSpecifier imageTypeSpecifier) {
+        return true;
+    }
+
+    @Override
+    public ImageWriter createWriterInstance(Object o) throws IOException {
+        return new JPEGImageWriter(this);
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "DRL JPEG Encoder";
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java
new file mode 100644
index 0000000..c3b4a50
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java
@@ -0,0 +1,57 @@
+/*
+ *  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 org.apache.harmony.x.imageio.plugins.jpeg;
+
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.2 $
+ */
+public class JPEGSpiConsts {
+    private JPEGSpiConsts() {}
+
+    public static final String vendorName = "Intel Corporation";
+    public static final String version = "0.1 beta";
+
+    static final String readerClassName = "org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReader";
+    static final String writerClassName = "org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriter";
+
+    static final String[] names = {"jpeg", "jpg", "JPEG", "JPG"};
+    static final String[] suffixes = {"jpeg", "jpg"};
+    static final String[] MIMETypes = {"image/jpeg"};
+
+    static final String[] writerSpiNames = {"org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageWriterSpi"};
+    static final String[] readerSpiNames = {"org.apache.harmony.x.imageio.plugins.jpeg.JPEGImageReaderSpi"};
+
+    //-- TODO fill this stuff with correct data
+    static final boolean supportsStandardStreamMetadataFormat = false;
+    static final String nativeStreamMetadataFormatName = null;
+    static final String nativeStreamMetadataFormatClassName = null;
+    static final String[] extraStreamMetadataFormatNames = null;
+    static final String[] extraStreamMetadataFormatClassNames = null;
+    static final boolean supportsStandardImageMetadataFormat = false;
+    static final String nativeImageMetadataFormatName =
+            "org.apache.harmony.x.imageio.plugins.jpeg.MyFormatMetadata_1.0";
+    static final String nativeImageMetadataFormatClassName =
+            "org.apache.harmony.x.imageio.plugins.jpeg.MyFormatMetadata";
+    static final String[] extraImageMetadataFormatNames = null;
+    static final String[] extraImageMetadataFormatClassNames = null;
+
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java
new file mode 100644
index 0000000..480041c
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java
@@ -0,0 +1,106 @@
+/*
+ *  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 org.apache.harmony.x.imageio.plugins.png;
+
+import org.apache.harmony.awt.gl.image.DecodingImageSource;
+import org.apache.harmony.awt.gl.image.OffscreenImage;
+import org.apache.harmony.x.imageio.plugins.jpeg.IISDecodingImageSource;
+
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageReadParam;
+import javax.imageio.plugins.jpeg.JPEGImageReadParam;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.metadata.IIOMetadata;
+import java.io.IOException;
+import java.util.Iterator;
+import java.awt.image.BufferedImage;
+
+public class PNGImageReader  extends ImageReader {
+    ImageInputStream iis;
+
+    public PNGImageReader(ImageReaderSpi imageReaderSpi) {
+        super(imageReaderSpi);
+    }
+
+    public int getNumImages(boolean allowSearch) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    public int getWidth(int imageIndex) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    public int getHeight(int imageIndex) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public IIOMetadata getStreamMetadata() throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public IIOMetadata getImageMetadata(int imageIndex) throws IOException {
+        //-- TODO imlement
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    @Override
+    public BufferedImage read(int i, ImageReadParam imageReadParam) throws IOException {
+        if (iis == null) {
+            throw new IllegalArgumentException("input stream == null");
+        }
+
+        DecodingImageSource source = new IISDecodingImageSource(iis);
+        OffscreenImage image = new OffscreenImage(source);
+        source.addConsumer(image);
+        source.load();
+        // The interrupted flag should be cleared because ImageDecoder interrupts
+        // current thread while decoding (due its architecture).
+        Thread.interrupted();
+        return image.getBufferedImage();
+    }
+
+    @Override
+    public BufferedImage read(int i) throws IOException {
+        return read(i, null);
+    }
+
+    @Override
+    public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
+        super.setInput(input, seekForwardOnly, ignoreMetadata);
+        iis = (ImageInputStream) input;
+    }
+
+    @Override
+    public ImageReadParam getDefaultReadParam() {
+        return new ImageReadParam();
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java
new file mode 100644
index 0000000..50f8b10
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java
@@ -0,0 +1,88 @@
+/*
+ *  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 org.apache.harmony.x.imageio.plugins.png;
+
+import org.apache.harmony.x.imageio.plugins.jpeg.JPEGSpiConsts;
+
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ServiceRegistry;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+import java.io.IOException;
+import java.util.Locale;
+
+public class PNGImageReaderSpi extends ImageReaderSpi {
+    static final String PNG_NAMES[] = new String[] {"png", "PNG"};
+    static final String PNG_SUFFIXES[] = new String[] {"png"};
+    static final String PNG_MIME_TYPES[] = new String[] {"image/png"};
+    static final String PNG_READER_CLASS_NAME = "org.apache.harmony.x.imageio.plugins.png.PNGImageReader";
+    static final String PNG_READER_SPI_NAMES[] = {"org.apache.harmony.x.imageio.plugins.png.PNGImageReaderSpi"};
+
+    public PNGImageReaderSpi() {
+        super(
+                JPEGSpiConsts.vendorName, JPEGSpiConsts.version,
+                PNG_NAMES, PNG_SUFFIXES,
+                PNG_MIME_TYPES, PNG_READER_CLASS_NAME,
+                STANDARD_INPUT_TYPE, null,
+                false, null,
+                null, null,
+                null, false, 
+                null, null,
+                null, null
+        );
+    }
+
+    @Override
+    public boolean canDecodeInput(Object source) throws IOException {
+        ImageInputStream markable = (ImageInputStream) source;
+        markable.mark();
+
+        byte[] signature = new byte[8];
+        markable.seek(0);
+
+        int nBytes = markable.read(signature, 0, 8);
+        if(nBytes != 8) markable.read(signature, nBytes, 8-nBytes);
+        markable.reset();
+
+        // PNG signature: 137 80 78 71 13 10 26 10
+        return  (signature[0] & 0xFF) == 137 &&
+                (signature[1] & 0xFF) == 80 &&
+                (signature[2] & 0xFF) == 78 &&
+                (signature[3] & 0xFF) == 71 &&
+                (signature[4] & 0xFF) == 13 &&
+                (signature[5] & 0xFF) == 10 &&
+                (signature[6] & 0xFF) == 26 &&
+                (signature[7] & 0xFF) == 10;
+    }
+
+    @Override
+    public ImageReader createReaderInstance(Object extension) throws IOException {
+        return new PNGImageReader(this);
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "DRL PNG decoder";
+    }
+
+    @Override
+    public void onRegistration(ServiceRegistry registry, Class<?> category) {
+        super.onRegistration(registry, category);
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java
new file mode 100644
index 0000000..e2a8d7d
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java
@@ -0,0 +1,247 @@
+/*
+ *  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 Viskov Nikolay
+ * @version $Revision$
+ */
+package org.apache.harmony.x.imageio.plugins.png;
+
+import com.android.internal.awt.ImageOutputStreamWrapper;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.IndexColorModel;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.stream.ImageOutputStream;
+
+import org.apache.harmony.x.imageio.internal.nls.Messages;
+
+import org.apache.harmony.luni.util.NotImplementedException;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+
+public class PNGImageWriter extends ImageWriter {
+    
+    // /* ???AWT: Debugging
+    private static final boolean DEBUG = false;
+    private static Bitmap bm;
+    public static Bitmap getBitmap() {
+        return bm;
+    }
+    // */
+    
+    private static int[][] BAND_OFFSETS = {
+            {}, {
+                0 }, {
+                    0, 1 }, {
+                    0, 1, 2 }, {
+                    0, 1, 2, 3 } };
+
+    // Each pixel is a grayscale sample.
+    private static final int PNG_COLOR_TYPE_GRAY = 0;
+    // Each pixel is an R,G,B triple.
+    private static final int PNG_COLOR_TYPE_RGB = 2;
+    // Each pixel is a palette index, a PLTE chunk must appear.
+    private static final int PNG_COLOR_TYPE_PLTE = 3;
+    // Each pixel is a grayscale sample, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_GRAY_ALPHA = 4;
+    // Each pixel is an R,G,B triple, followed by an alpha sample.
+    private static final int PNG_COLOR_TYPE_RGBA = 6;
+    
+    //???AWT: private static native void initIDs(Class<ImageOutputStream> iosClass);
+
+    static {
+        //???AWT
+        /*
+        System.loadLibrary("pngencoder"); //$NON-NLS-1$
+        initIDs(ImageOutputStream.class);
+        */
+    }
+    
+    /*
+    private native int encode(byte[] input, int bytesInBuffer, int bytePixelSize, Object ios, int imageWidth,
+            int imageHeight, int bitDepth, int colorType, int[] palette, int i, boolean b);
+    */
+    
+    protected PNGImageWriter(ImageWriterSpi iwSpi) {
+        super(iwSpi);
+    }
+
+    @Override
+    public IIOMetadata convertStreamMetadata(IIOMetadata arg0, ImageWriteParam arg1) {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public IIOMetadata convertImageMetadata(IIOMetadata arg0, ImageTypeSpecifier arg1, ImageWriteParam arg2) {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier arg0, ImageWriteParam arg1) {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public IIOMetadata getDefaultStreamMetadata(ImageWriteParam arg0) {
+        throw new NotImplementedException();
+    }
+
+    @Override
+    public void write(IIOMetadata streamMetadata, IIOImage iioImage, ImageWriteParam param) throws IOException {
+        if (output == null) {
+            throw new IllegalStateException("Output not been set");
+        }
+        if (iioImage == null) {
+            throw new IllegalArgumentException("Image equals null");
+        }
+        // AWT???: I think this is not needed anymore
+        // if (iioImage.hasRaster() && !canWriteRasters()) {
+        //    throw new UnsupportedOperationException("Can't write raster");
+        //}// ImageOutputStreamImpl
+        
+        Raster sourceRaster;
+        RenderedImage img = null;
+        if (!iioImage.hasRaster()) {
+            img = iioImage.getRenderedImage();
+            if (img instanceof BufferedImage) {
+                sourceRaster = ((BufferedImage) img).getRaster();
+            } else {
+                sourceRaster = img.getData();
+            }
+        } else {
+            sourceRaster = iioImage.getRaster();
+        }
+
+        SampleModel model = sourceRaster.getSampleModel();
+        int srcWidth = sourceRaster.getWidth();
+        int srcHeight = sourceRaster.getHeight();
+        int numBands = model.getNumBands();
+        
+        ColorModel colorModel = img.getColorModel();
+        int pixelSize = colorModel.getPixelSize();
+        int bytePixelSize = pixelSize / 8;
+        int bitDepth = pixelSize / numBands;
+        
+        // byte per band
+        int bpb = bitDepth > 8 ? 2 : 1;
+        
+        boolean isInterlace = true;
+        if (param instanceof PNGImageWriterParam) {
+            isInterlace = ((PNGImageWriterParam) param).getInterlace();
+        }
+        
+        int colorType = PNG_COLOR_TYPE_GRAY;
+        int[] palette = null;
+        
+        if (colorModel instanceof IndexColorModel) {
+            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8) {
+//              Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
+            }
+            if (numBands != 1) {
+//              Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
+            }
+
+            IndexColorModel icm = (IndexColorModel) colorModel;
+            palette = new int[icm.getMapSize()];
+            icm.getRGBs(palette);
+            colorType = PNG_COLOR_TYPE_PLTE;
+        }
+        else if (numBands == 1) {
+            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16) {
+//              Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
+            }
+            colorType = PNG_COLOR_TYPE_GRAY;
+        }
+        else if (numBands == 2) {
+            if (bitDepth != 8 && bitDepth != 16) {
+//              Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1"));//$NON-NLS-1$
+            }
+            colorType = PNG_COLOR_TYPE_GRAY_ALPHA;
+        }
+        else if (numBands == 3) {
+            if (bitDepth != 8 && bitDepth != 16) {
+//              Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1")); //$NON-NLS-1$
+            }
+            colorType = PNG_COLOR_TYPE_RGB;
+        }
+        else if (numBands == 4) {
+            if (bitDepth != 8 && bitDepth != 16) {
+                //Wrong bitDepth-numBands composition
+                throw new IllegalArgumentException(Messages.getString("imageio.1")); //$NON-NLS-1$
+            }
+            colorType = PNG_COLOR_TYPE_RGBA;
+        }
+        
+        /* ???AWT: I think this is not needed anymore
+        int dbufferLenght = bytePixelSize * imageHeight * imageWidth;
+        DataBufferByte dbuffer = new DataBufferByte(dbufferLenght);
+
+        WritableRaster scanRaster = Raster.createInterleavedRaster(dbuffer, imageWidth, imageHeight, bpb * numBands
+                * imageWidth, bpb * numBands, BAND_OFFSETS[numBands], null);
+
+        scanRaster.setRect(((BufferedImage) image).getRaster()// image.getData()
+                .createChild(0, 0, imageWidth, imageHeight, 0, 0, null));
+        */
+
+        if (DEBUG) {
+            System.out.println("**** raster:" + sourceRaster);        
+            System.out.println("**** model:" + model);
+            System.out.println("**** type:" + colorType);
+        }
+        
+        if (model instanceof SinglePixelPackedSampleModel) {
+            DataBufferInt ibuf = (DataBufferInt)sourceRaster.getDataBuffer();
+            int[] pixels = ibuf.getData();
+            
+            // Create a bitmap with the pixel
+            bm = Bitmap.createBitmap(pixels, srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
+            
+            // Use Bitmap.compress() to write the image
+            ImageOutputStream ios = (ImageOutputStream) getOutput();
+            ImageOutputStreamWrapper iosw = new ImageOutputStreamWrapper(ios);
+            bm.compress(CompressFormat.PNG, 100, iosw);
+        } else {
+            // ???AWT: Add support for other color models
+            throw new RuntimeException("Color model not supported yet");
+        }
+    }
+
+    public ImageWriteParam getDefaultWriteParam() {
+        return new PNGImageWriterParam();
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java
new file mode 100644
index 0000000..bf3a000
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java
@@ -0,0 +1,41 @@
+/*
+ *  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 Viskov Nikolay
+ * @version $Revision$
+ */
+package org.apache.harmony.x.imageio.plugins.png;
+
+import javax.imageio.ImageWriteParam;
+
+public class PNGImageWriterParam extends ImageWriteParam {
+
+    private boolean isInterlace = true;
+
+    public PNGImageWriterParam() {
+        super();
+    }
+
+    public boolean getInterlace() {
+        return isInterlace;
+    }
+
+    public void setInterlace(boolean b) {
+        isInterlace = b;
+    }
+
+}
diff --git a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java
new file mode 100644
index 0000000..6eed14d
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.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.
+ */
+/**
+ * @author Viskov Nikolay
+ * @version $Revision$
+ */
+package org.apache.harmony.x.imageio.plugins.png;
+
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferByte;
+import java.awt.image.IndexColorModel;
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriter;
+import javax.imageio.spi.ImageWriterSpi;
+
+public class PNGImageWriterSpi extends ImageWriterSpi {
+
+    public PNGImageWriterSpi() {
+        super("Intel Corporation",// vendorName
+                "1.0",// version
+                new String[] {
+                        "png", "PNG" },// names
+                new String[] {
+                        "png", "PNG" },// suffixes
+                new String[] {
+                    "image/png" },// MIMETypes
+                "org.apache.harmony.x.imageio.plugins.png.PNGImageWriter",// writerClassName
+                STANDARD_OUTPUT_TYPE,// outputTypes
+                new String[] {
+                    "org.apache.harmony.x.imageio.plugins.png.PNGImageWriterSpi" },// readerSpiNames
+                false,// supportsStandardStreamMetadataFormat
+                null,// nativeStreamMetadataFormatName
+                null,// nativeStreamMetadataFormatClassName
+                null,// extraStreamMetadataFormatNames
+                null,// extraStreamMetadataFormatClassNames
+                false,// supportsStandardImageMetadataFormat
+                null,// nativeImageMetadataFormatName
+                null,// nativeImageMetadataFormatClassName
+                null,// extraImageMetadataFormatNames
+                null// extraImageMetadataFormatClassNames
+        );
+    }
+
+    @Override
+    public boolean canEncodeImage(ImageTypeSpecifier type) {
+        boolean canEncode = true;
+
+        int numBands = type.getSampleModel().getNumBands();
+
+        ColorModel colorModel = type.getColorModel();
+
+        int bitDepth = colorModel.getPixelSize() / numBands;
+
+        if (colorModel instanceof IndexColorModel) {
+            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8) {
+                canEncode = false;
+            }
+            if (numBands != 1) {
+                canEncode = false;
+            }
+        }
+        else if (numBands == 1) {
+            if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16) {
+                canEncode = false;
+            }
+        }
+        else if (numBands == 2) {
+            if (bitDepth != 8 && bitDepth != 16) {
+                canEncode = false;
+            }
+        }
+        else if (numBands == 3) {
+            if (bitDepth != 8 && bitDepth != 16) {
+                canEncode = false;
+            }
+        }
+        else if (numBands == 4) {
+            if (bitDepth != 8 && bitDepth != 16) {
+                canEncode = false;
+            }
+        }
+
+        return canEncode;
+    }
+
+    @Override
+    public ImageWriter createWriterInstance(Object arg0) throws IOException {
+        return new PNGImageWriter(this);
+    }
+
+    @Override
+    public String getDescription(Locale arg0) {
+        return "DRL PNG encoder";
+    }
+
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java
new file mode 100644
index 0000000..d4fdd76
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java
@@ -0,0 +1,53 @@
+/*
+ *  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 org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageInputStreamSpi;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.FileImageOutputStream;
+import javax.imageio.stream.FileImageInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.Locale;
+
+public class FileIISSpi extends ImageInputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public FileIISSpi() {
+        super(vendor, ver, File.class);
+    }
+
+    @Override
+    public ImageInputStream createInputStreamInstance(Object input, boolean useCache,
+            File cacheDir) throws IOException {
+        if (File.class.isInstance(input)) {
+            return new FileImageInputStream((File) input);
+        }
+        throw new IllegalArgumentException("input is not an instance of java.io.File");
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "File IIS Spi";
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java
new file mode 100644
index 0000000..acda6a1
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java
@@ -0,0 +1,52 @@
+/*
+ *  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 org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageOutputStreamSpi;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.FileImageOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.Locale;
+
+public class FileIOSSpi extends ImageOutputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public FileIOSSpi() {
+        super(vendor, ver, File.class);
+    }
+
+    @Override
+    public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache,
+            File cacheDir) throws IOException {
+        if (output instanceof File) {
+            return new FileImageOutputStream((File) output);
+        }
+        throw new IllegalArgumentException("output is not instance of File");
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "File IOS Spi";
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java
new file mode 100644
index 0000000..ed2fef0
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java
@@ -0,0 +1,59 @@
+/*
+ *  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 org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageInputStreamSpi;
+import javax.imageio.stream.*;
+import java.io.OutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+
+public class InputStreamIISSpi extends ImageInputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public InputStreamIISSpi() {
+        super(vendor, ver, InputStream.class);
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "Output Stream IOS Spi";
+    }
+
+    @Override
+    public boolean canUseCacheFile() {
+        return true;
+    }
+
+    @Override
+    public ImageInputStream createInputStreamInstance(Object input, boolean useCache, File cacheDir) throws IOException {
+        if (input instanceof InputStream) {
+            if (useCache) {
+                return new FileCacheImageInputStream((InputStream) input, cacheDir);
+            } else {
+                return new MemoryCacheImageInputStream((InputStream) input);
+            }
+        }
+        throw new IllegalArgumentException("Output is not an instance of InputStream");
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java
new file mode 100644
index 0000000..dd1e88d
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java
@@ -0,0 +1,60 @@
+/*
+ *  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 org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageOutputStreamSpi;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.FileCacheImageOutputStream;
+import javax.imageio.stream.MemoryCacheImageOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Locale;
+
+public class OutputStreamIOSSpi extends ImageOutputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public OutputStreamIOSSpi() {
+        super(vendor, ver, OutputStream.class);
+    }
+
+    @Override
+    public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache, File cacheDir) throws IOException {
+        if (output instanceof OutputStream) {
+            if (useCache) {
+                return new FileCacheImageOutputStream((OutputStream) output, cacheDir);
+            } else {
+                return new MemoryCacheImageOutputStream((OutputStream) output);
+            }
+        }
+        throw new IllegalArgumentException("Output is not an instance of OutputStream");
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "Output Stream IOS Spi";
+    }
+
+    @Override
+    public boolean canUseCacheFile() {
+        return true;
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java b/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java
new file mode 100644
index 0000000..f97eb87
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java
@@ -0,0 +1,54 @@
+/*
+ *  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 org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageInputStreamSpi;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.FileImageInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Locale;
+
+public class RAFIISSpi extends ImageInputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public RAFIISSpi() {
+        super(vendor, ver, RandomAccessFile.class);
+    }
+
+    @Override
+    public ImageInputStream createInputStreamInstance(Object input, boolean useCache,
+            File cacheDir) throws IOException {
+        if (RandomAccessFile.class.isInstance(input)) {
+            return new FileImageInputStream((RandomAccessFile) input);
+        }
+        throw new IllegalArgumentException(
+                "input is not an instance of java.io.RandomAccessFile");
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "RandomAccessFile IIS Spi";
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java b/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java
new file mode 100644
index 0000000..a9d3649
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java
@@ -0,0 +1,53 @@
+/*
+ *  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 org.apache.harmony.x.imageio.spi;
+
+import javax.imageio.spi.ImageOutputStreamSpi;
+import javax.imageio.stream.ImageOutputStream;
+import javax.imageio.stream.FileImageOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Locale;
+
+public class RAFIOSSpi extends ImageOutputStreamSpi {
+    private static final String vendor = "Apache";
+
+    private static final String ver = "0.1";
+
+    public RAFIOSSpi() {
+        super(vendor, ver, RandomAccessFile.class);
+    }
+
+    @Override
+    public ImageOutputStream createOutputStreamInstance(Object output, boolean useCache,
+            File cacheDir) throws IOException {
+        if (output instanceof RandomAccessFile) {
+            return new FileImageOutputStream((RandomAccessFile) output);
+        }
+        throw new IllegalArgumentException("output is not instance of java.io.RandomAccessFile");
+    }
+
+    @Override
+    public String getDescription(Locale locale) {
+        return "RandomAccessFile IOS Spi";
+    }
+}
diff --git a/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java b/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java
new file mode 100644
index 0000000..64f7b2a
--- /dev/null
+++ b/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java
@@ -0,0 +1,226 @@
+/*
+ *  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 org.apache.harmony.x.imageio.stream;
+
+import java.util.ArrayList;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public final class RandomAccessMemoryCache {
+    private static final int BLOCK_SHIFT = 9;
+    private static final int BLOCK_SIZE = 1 << BLOCK_SHIFT;
+    private static final int BLOCK_MASK = BLOCK_SIZE - 1;
+    
+    private long length;
+
+    private int firstUndisposed = 0;
+
+    private ArrayList<byte[]> blocks = new ArrayList<byte[]>();
+
+    public RandomAccessMemoryCache() {
+    }
+
+    public long length() {
+        return length;
+    }
+
+    public void close() {
+        blocks.clear();
+        length = 0;
+    }
+
+    private void grow(long pos) {
+        int blocksNeeded = (int)(pos >> BLOCK_SHIFT) - blocks.size() + 1;
+        for (int i=0; i < blocksNeeded; i++) {
+            blocks.add(new byte[BLOCK_SIZE]);
+        }
+
+        length = pos + 1;
+    }
+
+    public void putData(int oneByte, long pos) {
+        if (pos >= length) {
+            grow(pos);
+        }
+
+        byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
+        block[(int)(pos & BLOCK_MASK)] = (byte) oneByte;
+    }
+
+    public void putData(byte[] buffer, int offset, int count, long pos) {
+        if (count > buffer.length - offset || count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0){
+            return;
+        }
+
+        long lastPos = pos + count - 1;
+        if (lastPos >= length) {
+            grow(lastPos);
+        }
+
+        while (count > 0) {
+            byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
+            int blockOffset = (int)(pos & BLOCK_MASK);
+            int toCopy = Math.min(BLOCK_SIZE - blockOffset, count);
+            System.arraycopy(buffer, offset, block, blockOffset, toCopy);
+            pos += toCopy;
+            count -= toCopy;
+            offset += toCopy;
+        }
+    }
+
+    public int getData(long pos) {
+        if (pos >= length) {
+            return -1;
+        }
+
+        byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
+        return block[(int)(pos & BLOCK_MASK)] & 0xFF;
+    }
+
+    public int getData(byte[] buffer, int offset, int count, long pos) {
+        if (count > buffer.length - offset || count < 0 || offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (count == 0) {
+            return 0;
+        }
+        if (pos >= length) {
+            return -1;
+        }
+
+        if (count + pos > length) {
+            count = (int) (length - pos);
+        }
+
+        byte[] block = blocks.get((int)(pos >> BLOCK_SHIFT));
+        int nbytes = Math.min(count, BLOCK_SIZE - (int)(pos & BLOCK_MASK));
+        System.arraycopy(block, (int)(pos & BLOCK_MASK), buffer, offset, nbytes);
+
+        return nbytes;
+    }
+    /*
+    public void seek(long pos) throws IOException {
+        if (pos < 0) {
+            throw new IOException("seek position is negative");
+        }
+        this.pos = pos; 
+    }
+
+    public void readFully(byte[] buffer) throws IOException {
+        readFully(buffer, 0, buffer.length);
+    }
+
+    public void readFully(byte[] buffer, int offset, int count) throws IOException {
+        if (0 <= offset && offset <= buffer.length && 0 <= count && count <= buffer.length - offset) {
+            while (count > 0) {
+                int result = read(buffer, offset, count);
+                if (result >= 0) {
+                    offset += result;
+                    count -= result;
+                } else {
+                    throw new EOFException();
+                }
+            }
+        } else {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    public long getFilePointer() {
+        return pos;
+    }
+*/
+
+    public void freeBefore(long pos) {
+        int blockIdx = (int)(pos >> BLOCK_SHIFT);
+        if (blockIdx <= firstUndisposed) { // Nothing to do
+            return;
+        }
+
+        for (int i = firstUndisposed; i < blockIdx; i++) {
+            blocks.set(i, null);
+        }
+
+        firstUndisposed = blockIdx;
+    }
+
+    public int appendData(InputStream is, int count) throws IOException {
+        if (count <= 0) {
+            return 0;
+        }
+
+        long startPos = length;
+        long lastPos = length + count - 1;
+        grow(lastPos); // Changes length
+
+        int blockIdx = (int)(startPos >> BLOCK_SHIFT);
+        int offset = (int) (startPos & BLOCK_MASK);
+
+        int bytesAppended = 0;
+
+        while (count > 0) {
+            byte[] block = blocks.get(blockIdx);
+            int toCopy = Math.min(BLOCK_SIZE - offset, count);
+            count -= toCopy;
+
+            while (toCopy > 0) {
+                int bytesRead = is.read(block, offset, toCopy);
+
+                if (bytesRead < 0) {
+                    length -= (count - bytesAppended);
+                    return bytesAppended;
+                }
+
+                toCopy -= bytesRead;
+                offset += bytesRead;
+            }
+
+            blockIdx++;
+            offset = 0;
+        }
+
+        return count;
+    }
+
+    public void getData(OutputStream os, int count, long pos) throws IOException {
+        if (pos + count > length) {
+            throw new IndexOutOfBoundsException("Argument out of cache");
+        }
+
+        int blockIdx = (int)(pos >> BLOCK_SHIFT);
+        int offset = (int) (pos & BLOCK_MASK);
+        if (blockIdx < firstUndisposed) {
+            throw new IndexOutOfBoundsException("The requested data are already disposed");
+        }
+
+        while (count > 0) {
+            byte[] block = blocks.get(blockIdx);
+            int toWrite = Math.min(BLOCK_SIZE - offset, count);
+            os.write(block, offset, toWrite);
+
+            blockIdx++;
+            offset = 0;
+            count -= toWrite;
+        }
+    }
+}
diff --git a/awt/resources/org/apache/harmony/awt/internal/nls/messages.properties b/awt/resources/org/apache/harmony/awt/internal/nls/messages.properties
new file mode 100644
index 0000000..9f647e9
--- /dev/null
+++ b/awt/resources/org/apache/harmony/awt/internal/nls/messages.properties
@@ -0,0 +1,495 @@
+# 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.
+# 
+
+# messages for EN locale
+awt.00=FontRenderContext is null
+awt.01='{0}' parameter is null
+awt.02='{0}' parameter has zero length
+awt.03='{0}' iterator parameter is null
+awt.04='{0}' iterator parameter has zero length
+awt.05=Operation cannot be null
+awt.06=Unexpected type of the internal data buffer
+awt.07=Transfer data is not available
+awt.08=xfld parse string error: {0}
+awt.09=min range bound value is greater than max range bound
+awt.0A=Cannot use SinglePixedPackedSampleModel for bpp = {0}
+awt.0B=Wrong color model created for drawable
+awt.0C=Unknown visual class
+awt.0D=Invalid transparency
+awt.0E=Dimensions of the image should be positive
+awt.0F=Cannot open display '{0}'
+awt.10=Only 32-bit format is supported for window state operations.
+awt.11=Invalid key code
+awt.12=XTest is not supported by your X server\!
+awt.13=Cannot allocate color named '{0}'
+awt.14=Transfer data is not available
+awt.15=Can not get monitor info
+awt.16=Can not create DC for device
+awt.17=Unknown Composite type : {0}
+awt.18=Transparency is not supported
+awt.19=Illegal size of volatile image
+awt.1A=Failed to register window class {0} GetLastError returned {1}
+awt.1B=Invalid key code
+awt.1C=Failure to create JavaWindow GetLastError returned {0}
+awt.1D=Cannot get data from OLE clipboard
+awt.1E=Attempt to replace WindowProc handler
+awt.1F=Waiting for resource access thread interrupted not from unlock method
+awt.20=Can't unlock not locked resource
+awt.21=Not owner can't unlock resource
+awt.22=Not owner can't free resource
+awt.23=One thread can't store state several times in a row
+awt.24=Owner can't overwrite resource state. Lock operations may be lost
+awt.25=No state stored for current thread
+awt.26=Shutdown thread was interrupted while starting
+awt.27=Shutdown thread was interrupted while stopping
+awt.28=bad index: {0}
+awt.29=Invalid range
+awt.2A=Position not represented by view
+awt.2B=No word at {0}
+awt.2C=Invalid position: {0}
+awt.2D=Invalid direction
+awt.2E={0} not in range {1},{2}
+awt.2F=No more words
+awt.30=wrong number of elements to copy: {0}, size: {1}
+awt.31=no room to copy: {0}, size: {1}
+awt.32=String: '{0}' does not fit
+awt.33=index is out of range
+awt.34=Initial offset in the destination array is wrong: {0}
+awt.35=Wrong number of elements to copy: {0}
+awt.36=Wrong segment
+awt.37=Unknown  composite type {0}
+awt.38=Property name is not defined
+awt.39=This method is not implemented for image obtained from ImageProducer
+awt.3A=Color Model is null
+awt.3B=Incorrect ImageConsumer completion status
+awt.3C=Unknown PNG color type
+awt.3D=Unknown colorspace
+awt.3E=Clone not supported
+awt.3F=Invalid baseline index
+awt.40=Wrong number of metrics\!
+awt.41=Font returned unsupported type of line metrics. This case is known, but not supported yet.
+awt.42=TextHitInfo out of range
+awt.43=glyphIndex is out of vector's limits
+awt.44=beginGlyphIndex is out of vector's range
+awt.45=numEntries is out of vector's range
+awt.46=length of setPositions array differs from the length of positions array
+awt.47=First argument should be byte or short array
+awt.48=The srcIn raster is incompatible with src ColorModel
+awt.49=The dstIn raster is incompatible with dst ColorModel
+awt.4A=The dstOut raster is incompatible with dst ColorModel
+awt.4B=Iterator out of bounds
+awt.4C=Invalid MultiRectArea in method {0}
+awt.4D=The raster is incompatible with this ColorModel
+awt.4E=Unknown native platform.
+awt.4F=Data is not available
+awt.50=Iterator is read-only
+awt.51=Component expected to be a parent
+awt.52=Time interval can't be <= 0
+awt.53=Handler can't be null
+awt.54=Key event for unfocused component
+awt.55=Double mouse enter event for component
+awt.56=Double mouse exit event for component
+awt.57=Double focus gained event for component
+awt.58=Double focus lost event for component
+awt.59=Application has run out of context thread group
+awt.5A=Default class for PrinterJob is not found
+awt.5B=No access to default class for PrinterJob
+awt.5C=Instantiation exception for PrinterJob
+awt.5D={0} is not supported
+awt.5E=pageIndex is more than book size
+awt.5F=wrong orientation
+awt.60=Width and Height mustn't be equal zero both
+awt.61=Unsupported data type: {0}
+awt.62=Wrong mask : {0}
+awt.63=Coordinates are not in bounds
+awt.64=The number of the bands in the subset is greater than the number of bands in the sample model
+awt.65=null argument
+awt.66=Invalid format
+awt.67=subclass is not derived from AWTKeyStroke
+awt.68=subclass could not be instantiated
+awt.69=columns less than zero.
+awt.6A=rows less than zero.
+awt.6B=Queue stack is empty
+awt.6C=Event queue stack is broken
+awt.6D=Point is null
+awt.6E=Color is null
+awt.6F=Index less than zero
+awt.70=MenuItem is null
+awt.71=Parent is null
+awt.72=Key event for unfocused component
+awt.73=no such item
+awt.74=Input parameters a and b should not be null
+awt.75=rows and cols cannot both be zero
+awt.76=rows and cols cannot be negative
+awt.77=default focus traversal policy cannot be null
+awt.78=invalid focus traversal key identifier
+awt.79=cannot set null focus traversal key
+awt.7A=focus traversal keys cannot map to KEY_TYPED events
+awt.7B=focus traversal keys must be unique for a Component
+awt.7C=this KeyboardFocusManager is not installed in the current thread's context
+awt.7D=Property name is null
+awt.7E=invalid hotSpot
+awt.7F=AddLayoutComponent: attempt to add null component
+awt.80=AddLayoutComponent: constraint object must be GridBagConstraints
+awt.81=AddLayoutComponent: {0}
+awt.82=RemoveLayoutComponent: attempt to remove null component
+awt.83=SetConstraints: attempt to get constraints of null component
+awt.84=SetConstraints: attempt to set null constraints
+awt.85=SetConstraints: {0}
+awt.86=MinimumLayoutSize: {0}
+awt.87=PreferredLayoutSize: {0}
+awt.88=LayoutContainer: {0}
+awt.89=LookupConstraints: attempt to get constraints of null component
+awt.8A=AdjustForGravity: attempt to use null constraints
+awt.8B=AdjustForGravity: attempt to use null rectangle
+awt.8C=AdjustForGravity: {0}
+awt.8D=REMINDER component expected after RELATIVE one
+awt.8E=component is out of grid's range
+awt.8F=Weights' overrides array is too long
+awt.90=Lengths' overrides array is too long
+awt.91=Unsupported constraints object: {0}
+awt.92=Constraints object must be String
+awt.93=cannot get component: invalid constraint: {0}
+awt.94=transform can not be null
+awt.95=Wrong start index: {0}
+awt.96=Wrong finish index: {0}
+awt.97=Wrong range length: {0}
+awt.98=Wrong count value, can not be negative: {0}
+awt.99=Wrong [start + count] is out of range: {0}
+awt.9A=Unsupported font format
+awt.9B=Can't create font - bad font data
+awt.9C=wrong value of GridBagConstraints: {0}
+awt.9D=relative grid size parameter goes after absolute grid coordinate
+awt.9E=wrong values sum of GridBagConstraints' gridwidth and gridx
+awt.9F=wrong values sum of GridBagConstraints' gridheight and gridy
+awt.100=component has RELATIVE width and height
+awt.101=position less than zero.
+awt.102=columns less than zero.
+awt.103=item is null
+awt.104=item doesn't exist in the choice menu
+awt.105=index less than zero
+awt.106=specified position is greater than the number of items
+awt.107=Color parameter outside of expected range: component {0}
+awt.108=Alpha value outside of expected range
+awt.109=Color parameter outside of expected range
+awt.10A=Priority must be a value between 0 and 1, inclusive
+awt.10B=aContainer and aComponent cannot be null
+awt.10C=aContainer is not a focus cycle root of aComponent
+awt.10D=aContainer should be focus cycle root or focus traversal policy provider
+awt.10E=focusCycleRoot cannot be null
+awt.10F=improper alignment: {0}
+awt.110=Iterator out of bounds
+awt.111=Parameter npoints is greater than array length
+awt.112=Negative number of points
+awt.113=illegal scrollbar orientation
+awt.114=Image is null
+awt.115=Anchor is null
+awt.116=Invalid value for media
+awt.117=Invalid value for orientationRequested
+awt.118=Invalid value for printerResolution
+awt.119=Invalid value for origin
+awt.11A=Invalid value for printQuality
+awt.11B=Invalid value for printerResolution[]
+awt.11C=Invalid value for color
+awt.11D=Unknown rule
+awt.11E=Wrong alpha value
+awt.11F=parent is not a component
+awt.120=origin is not a descendant of parent
+awt.121=parent must be showing on the screen
+awt.122=Does not support display mode changes
+awt.123=Unsupported display mode: {0}
+awt.124=Cannot change the modality while the dialog is visible
+awt.125=null owner window
+awt.126=Window is showing
+awt.127=Cannot change the decorations while the window is visible
+awt.128=Graphics environment is headless
+awt.129=Not a screen device
+awt.12A=illegal component position
+awt.12B=adding container to itself
+awt.12C=adding container's parent to itself
+awt.12D=adding a window to a container
+awt.12E=Unknown component event id
+awt.12F=Attempt to start nested mouse grab
+awt.130=Attempt to grab mouse in not displayable window
+awt.131=AddLayoutComponent: constraint object must be String
+awt.132=wrong parent for CardLayout
+awt.133=Negative width
+awt.134=Illegal cap
+awt.135=Illegal join
+awt.136=miterLimit less than 1.0f
+awt.137=Negative dashPhase
+awt.138=Zero dash length
+awt.139=Negative dash[{0}]
+awt.13A=All dash lengths zero
+awt.13B=offset off is out of range
+awt.13C=number of elemets len is out of range
+awt.13D=Rectangle width and height must be > 0
+awt.13E=Cannot call method from the event dispatcher thread
+awt.13F=Delay must be to 0 to 60,000ms
+awt.140=Invalid combination of button flags
+awt.141=failed to parse hotspot property for cursor: 
+awt.142=Exception: class {0} {1} occurred while loading: {2}
+awt.143=illegal cursor type
+awt.144=Can be set by scrollpane only
+awt.145=illegal file dialog mode
+awt.146=illegal scrollbar display policy
+awt.147=position greater than 0
+awt.148=child is null
+awt.149=ScrollPane controls layout
+awt.14A=Can not create VolatileImage with specified capabilities
+awt.14B=Only Canvas or Window is allowed
+awt.14C=Number of buffers must be greater than one
+awt.14D=Buffer capabilities should support flipping
+awt.14E=Component should be displayable
+awt.14F=invalid focus traversal key identifier
+awt.150=no parent
+awt.151=component must be showing on the screen to determine its location
+awt.152=Invalid number of copies
+awt.153=Invalid value for maxPage
+awt.154=Invalid value for minPage
+awt.155=Invalid value for fromPage
+awt.156=Invalid value for toPage
+awt.157=Invalid value for pageRanges
+awt.158=Invalid value for destination
+awt.159=Invalid value for dialog
+awt.15A=Invalid value for defaultSelection
+awt.15B=Invalid value for multipleDocumentHandling
+awt.15C=Invalid value for attribute sides
+awt.15D=Invalid colorspace
+awt.15E=Unknown component. Must be REDCOMPONENT, GREENCOMPONENT or BLUECOMPONENT.
+awt.15F=Profile class does not comply with ICC specification
+awt.160=Color space doesn't comply with ICC specification
+awt.161=Unable to open file {0}
+awt.162=Invalid ICC Profile Data
+awt.163=Can't open color profile
+awt.164=Not a predefined color space
+awt.165=Color space doesn't comply with ICC specification
+awt.166=TRC is not a simple gamma value
+awt.167=TRC is a gamma value, not a table
+awt.168=Invalid profile class
+awt.169=Component index out of range
+awt.16A=Invalid component index: {0}
+awt.16B=Not a predefined colorspace
+awt.16C=Can't load class: {0}
+awt.16D=Can't parse MIME type: {0}
+awt.16E=Transferable has null data
+awt.16F=Can't create reader for this representation class
+awt.170=Can't create default D&D cursor: {0}
+awt.171=Attempt to start a drag while an existing drag operation is still executing
+awt.172=Drag source is null
+awt.173=One listener is already exist
+awt.174=dgl is not current listener
+awt.175=Listener mismatch
+awt.176=DropTarget cannot be added as listener to itself
+awt.177=Invalid user action
+awt.178=Invalid source action
+awt.179=Context peer is null
+awt.17A=Trigger event is null
+awt.17B=Can't init ACTION_NONE drag
+awt.17C=Image offset is null
+awt.17D=Transferable is null
+awt.17E=Component associated with the trigger event is null
+awt.17F=DragSource for the trigger event is null
+awt.180=Source actions for the DragGestureRecognizer associated with the trigger event are equal to DnDConstants.ACTION_NONE
+awt.181=Attempt to register context as its listener
+awt.182=dsl is not current listener
+awt.183=Invalid status
+awt.184=Invalid action
+awt.185=Component is null
+awt.186=DragSource is null
+awt.187=Origin is null
+awt.188=Event list is null
+awt.189=Event list is empty
+awt.18A=Context is null
+awt.18B=Invalid button value
+awt.18C=Cannot invoke null runnable
+awt.18D=Source is null
+awt.18E=Wrong event id
+awt.18F=Text must be null for CARET_POSITION_CHANGED
+awt.190=Wrong committedCharacterCount
+awt.191=Invalid keyCode for KEY_TYPED event, must be VK_UNDEFINED
+awt.192=Invalid keyChar for KEY_TYPED event, can't be CHAR_UNDEFINED
+awt.193=Listener can't be zero
+awt.194=Unknown attribute name
+awt.195=Offset is out of bounds
+awt.196=Justification impossible, layout already justified
+awt.197=Endpoints are out of range
+awt.198=Illegal alignment argument
+awt.199=Illegal range argument value: {0}
+awt.19A=start or count arguments are out of text range
+awt.19B=count argument must be positive
+awt.19C=weight must be a positive number
+awt.19D=growLeftLimit must be a positive number
+awt.19E=growRightLimit must be a positive number
+awt.19F=incorrect value for shrinkPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
+awt.200=incorrect value for growPriority, more than PRIORITY_NONE or less than PRIORITY_KASHIDA value
+awt.201=shrinkLeftLimit must be a positive number
+awt.202=shrinkRightLimit must be a positive number
+awt.203=Offset limit should be greater than current position
+awt.204=Determinant is zero
+awt.205=Invalid type of Arc: {0}
+awt.206=Flatness is less then zero
+awt.207=Limit is less then zero
+awt.208=Path is null
+awt.209=Invalid winding rule value
+awt.20A=First segment should be SEG_MOVETO type
+awt.20B=unknown input method highlight state
+awt.20C=Number of Bits equals to zero
+awt.20D=The number of bits per pixel is not a power of 2 or pixels span data element boundaries
+awt.20E=Data Bit offset is not a multiple of pixel bit stride
+awt.20F=Number of bands must be only 1
+awt.210=The component value for this ColorModel is signed
+awt.211=Pixel values for this ColorModel are not conveniently representable as a single int
+awt.212=There is more than one component in this ColorModel
+awt.213=This ComponentColorModel does not support the unnormalized form
+awt.214=This Color Model doesn't support this transferType
+awt.215=transferType is not one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE
+awt.216=The components array is not large enough to hold all the color and alpha components
+awt.217=The transfer type of this ComponentColorModel is not one of the following transfer types: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
+awt.218=The components array is not large enough to hold all the color and alpha components
+awt.219=This transferType is not supported by this color model
+awt.21A=This ComponentColorModel does not support this transferType
+awt.21B=The length of normComponents minus normOffset is less than numComponents
+awt.21C=The number of scale factors should not be zero
+awt.21D=Number of src bands ({0}) does not match number of dst bands ({1})
+awt.21E=Number of scaling constants is not equal to the number of bands
+awt.21F=Unable to transform source
+awt.220=Source should not have IndexColorModel
+awt.221=The imageType is TYPE_BYTE_BINARY and the color map has more than 16 entries
+awt.222=The imageType is not TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED
+awt.223=The imageType is not compatible with ColorModel
+awt.224=Unknown image type
+awt.225=Property name is null
+awt.226=Both tileX and tileY are not equal to 0
+awt.227=This image type can't have alpha
+awt.228=minX or minY of this raster not equal to zero
+awt.229=Number of components in the LUT does not match the number of bands
+awt.22A=Wrong type of pixels array
+awt.22B=Length of data should not be less than width*height
+awt.22C=Unknown data type {0}
+awt.22D=This transferType ( {0} ) is not supported by this color model
+awt.22E=w or h is less than or equal to zero
+awt.22F=The product of w and h is greater than Integer.MAX_VALUE
+awt.230=dataType is not one of the supported data types
+awt.231=Number of bands must be more then 0
+awt.232=Offset should be not less than zero
+awt.233=Number of components should be positive
+awt.234=Width or Height equals zero
+awt.235=Wrong Data Buffer type : {0}
+awt.236=The bits is less than 1 or greater than 32
+awt.237=Source and destinations rasters do not have the same number of bands
+awt.238=The number of arrays in the LookupTable does not meet the restrictions
+awt.239=The space is not a TYPE_RGB space
+awt.23A=The min/max normalized component values are not 0.0/1.0
+awt.23B=The mask of the {0} component is not contiguous
+awt.23C=The mask of the alpha component is not contiguous
+awt.23D=The mask of the red component is not contiguous
+awt.23E=The mask of the green component is not contiguous
+awt.23F=The mask of the blue component is not contiguous
+awt.240=The transferType not is one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT or DataBuffer.TYPE_INT
+awt.241=Any offset between bands is greater than the Scanline stride
+awt.242=Pixel stride is less than any offset between bands
+awt.243=Product of Pixel stride and w is greater than Scanline stride
+awt.244=Width or Height of child Raster is less than or equal to zero
+awt.245=parentX disposes outside Raster
+awt.246=parentY disposes outside Raster
+awt.247=parentX + w results in integer overflow
+awt.248=parentY + h results in integer overflow
+awt.249=childMinX + w results in integer overflow
+awt.24A=childMinY + h results in integer overflow
+awt.24B=Pixel stride must be >= 0
+awt.24C=Scanline stride must be >= 0
+awt.24D=Bank Indices length must be equal Bank Offsets length
+awt.24E=Index of {0} bank must be >= 0
+awt.24F=Unable to invert transform {0}
+awt.250=Unknown interpolation type: {0}
+awt.251=Transformed width ({0}) and height ({1}) should be greater than 0
+awt.252=Source can't be same as the destination
+awt.253=Different number of bands in source and destination
+awt.254=Number of bands in the source raster ({0}) is incompatible with the matrix [{1}x{2}]
+awt.255=Number of bands in the destination raster ({0}) is incompatible with the matrix [{1}x{2}]
+awt.256=Source raster is null
+awt.257=Source raster is equal to destination
+awt.258=Number of source bands ({0}) is not equal to number of destination bands ({1})
+awt.259=Source image is null
+awt.25A=Source equals to destination
+awt.25B=Null ColorSpace passed as a parameter
+awt.25C=Null profiles passed as a parameter
+awt.25D=Source or destination color space is not defined
+awt.25E=Incorrect number of source raster bands. Should be equal to the number of color components of source colorspace.
+awt.25F=Incorrect number of destination raster bands. Should be equal to the number of color components of destination colorspace.
+awt.260=Incompatible rasters - width or height differs
+awt.261=Destination color space is undefined
+awt.262=Destionation color space should be defined
+awt.263=Incompatible images - width or height differs
+awt.264=Size of the color map is less than 1
+awt.265=The raster argument is not compatible with this IndexColorModel
+awt.266=The number of bits in a pixel is greater than 16
+awt.267=The transferType is invalid
+awt.268=The pixel is not a primitive array of type transferType
+awt.269=The transferType is not one of DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT
+awt.26A=Incorrect ImageConsumer completion status
+awt.26B=The number of bits in the pixel values is less than 1
+awt.26C=bits is null
+awt.26D=The elements in bits is less than 0
+awt.26E=The sum of the number of bits in bits is less than 1
+awt.26F=The cspace is null
+awt.270=The transparency is not a valid value
+awt.271=The number of bits in bits is less than 1
+awt.272=The length of components minus offset is less than numComponents
+awt.273=The length of normComponents minus normOffset is less than numComponents
+awt.274=componentIdx is greater than the number of components or less than zero
+awt.275=This pixel representation is not suuported by tis Color Model
+awt.276=location.x + w or location.y + h results in integer overflow
+awt.277=bankIndices or bandOffsets is null
+awt.278=dataBuffer is null
+awt.279=bands is less than 1
+awt.27A=dataBuffer has more than one bank
+awt.27B=bandOffsets is null
+awt.27C=bandMasks is null
+awt.27D=bitsPerBand or bands is not greater than zero
+awt.27E=The product of bitsPerBand and bands is greater than the number of bits held by dataType
+awt.27F=SampleModel or DataBuffer is null
+awt.280=SampleModel is null
+awt.281=sampleModel, dataBuffer, aRegion or sampleModelTranslate is null
+awt.282=aRegion has width or height less than or equal to zero
+awt.283=Overflow X coordinate of Raster
+awt.284=Overflow Y coordinate of Raster
+awt.285=Width or Height of child Raster is less than or equal to zero
+awt.286=parentX disposes outside Raster
+awt.287=parentY disposes outside Raster
+awt.288=parentX + width results in integer overflow
+awt.289=parentY + height results in integer overflow
+awt.28A=childMinX + width results in integer overflow
+awt.28B=childMinY + height results in integer overflow
+awt.28C=Rect is null
+awt.28D=Length of dataArray[{0}] is less than size + offset[{1}]
+awt.28E=Length of dataArray is less than size + offset
+awt.28F=Source and destination rasters do not have the same width!
+awt.290=Source and destination rasters do not have the same height!
+awt.291=Source and destination images do not have the same width!
+awt.292=Source and destination images do not have the same height!
+awt.294=pixel is null
+awt.295=data is null
+awt.296=can't allocate memory on video card to create new display list
+awt.297=Invalid keyLocation
+awt.298=dataBuffer is too small
+
+awt.err.00=file dialog {0} error!
+awt.err.01=error: {0}
+awt.err.02=GDIPlus DrawDriverString error status = {0}
+awt.err.03=gdipDrawCompositeGlyphVector: GDIPlus DrawDriverString error status = {0}
+awt.err.04=gdipDrawCompositeGlyphVector: GDIPlus DrawDriverString error status = {0}
